You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fetch+Redux获取内容无法稳定显示的问题及解决

问题:本地Fetch接口展示Tweet功能异常

发布内容时会随机不显示该内容,发布新内容时会同时显示两条(包含之前未显示的那条)。

Home.js组件代码(原版本)

function Home() {
    const dispatch = useDispatch();

    const [message, setMessage] = useState("")
    const [characters, setCharacters] = useState([])
    const [charactersStyle, setCharactersStyle] = useState({})
    const user = useSelector((state) => state.user.value)
    const [posted, setPosted] = useState(false)

    useEffect(() => {
        setCharacters(message.length)
    }, [message])

    useEffect(() => {
        if (message.length > 280) {
            setCharactersStyle({ "color": "red" })
        }
        else { setCharactersStyle({}) }
    }, [message])

    const handleTweet = () => {
        if (message.length > 0 && message.length <= 280) {

            const regex = /\B\#[a-zA-Z]+\b(?!;)/

            fetch("http://localhost:3000/tweets/new", {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ username: user.username, message }),
            })
                .then(response => response.json())
                .then(data => {
                    setMessage("")
                    setPosted(!posted)
                    dispatch(add(message.match(regex)))
                })
        }
    }
    const fetchTweets = async () => {

        const response = await fetch("http://localhost:3000/tweets/all")
        const data = await response.json()
        console.log(data.tweets)
        dispatch(post(data.tweets))
    }
    
    useEffect(() => {
        fetchTweets();
    }, [posted])

    return (
        <div className={styles.container}>
            <h1>Home</h1>
            <div className={styles.inputcontainer}>
                <textarea className={styles.input} onChange={(e) => setMessage(e.target.value)} value={message} ></textarea>
                <div className={styles.charbtn}>
                    <p className={styles.characters} style={charactersStyle}>{`${characters}/280`}</p>
                    <button type="button" className={styles.tweetbtn} onClick={() => { handleTweet() }}>Tweet</button>
                </div>
            </div>
            <LastTweets posted={posted} />
        </div>
    )
}

export default Home;

LastTweets.js组件代码

function LastTweets() {
    const tweetsToDisplay = useSelector((state) => state.tweets.value)

    console.log(tweetsToDisplay)

    let tweets;
    if (tweetsToDisplay.length > 0) {
        tweets = tweetsToDisplay.map((data, i) => {
            return <Tweet key={i} {...data} />
        })
    }

    return (
        <div>
            {tweets}
        </div>
    )
}

export default LastTweets;

尝试过程与解决方法

最初尝试在LastTweets组件中调用GET Fetch,问题未解决。按照建议修改fetchTweets函数后,功能恢复正常,修改后的代码如下:

const fetchTweets = async () => {
    const response = await fetch("http://localhost:3000/tweets/all")
    const data = await response.json()
    dispatch(post(data.tweets))
    setPosted(false)
}

原代码中handleTweet通过setPosted(!posted)切换状态触发数据拉取,但异步请求完成前若再次触发状态切换,会导致状态不一致或重复请求。修改后在fetchTweets末尾将posted重置为false,确保每次发布后只触发一次有效数据拉取,避免状态反复切换引发的异常。

内容的提问来源于stack exchange,提问作者david33

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 19:20:08