React useNavigate跳转异常及搜索页数据为空问题求助
问题解答
一、URL自动变成/search?search=music的原因及解决
这是表单默认提交行为导致的:
当你点击提交按钮或按回车时,浏览器会自动触发表单的默认提交逻辑——把表单里所有带name属性的输入框,以name=value的格式拼到URL里提交。你的搜索输入框name="search",所以默认提交后URL就变成了/search?search=music。
你写的navigate(/search?q=${search})会先执行,但紧接着浏览器的默认提交就覆盖了这个跳转,所以你会看到URL先变成/search?q=music又立刻变成/search?search=music。
修复代码:在handleSearch里加上e.preventDefault()阻止默认行为:
const handleSearch = (e) => { e.preventDefault(); // 阻止表单默认提交 navigate(`/search?q=${search}`); }
二、dispatch后posts数组仍为空的原因及解决
主要有三个核心问题:
- 异步请求时序错误:
dispatch(getPosts(key))是异步操作,你在dispatch之后立刻setLoading(false)并console.log(posts),这时候redux里的posts还没更新,打印的自然是初始空数组。 - useEffect依赖缺失:你的useEffect依赖是空数组,只会执行一次。如果搜索词
key变化了,不会重新触发请求。 - 闭包导致旧值引用:useEffect里的
posts是初始渲染时的闭包值,即使redux状态更新了,这里打印的还是旧的空数组。
修复步骤&代码:
export const SearchedPosts = () => { const location = useLocation(); const dispatch = useDispatch(); const posts = useSelector((state)=> state.newReducer.posts); const query = new URLSearchParams(location.search); const [isLoading, setLoading] = useState(true); const key= query.get('q'); useEffect(() => { if (!key) return; setLoading(true); // 假设getPosts返回Promise(redux-thunk的常见写法) dispatch(getPosts(key)) .then(() => setLoading(false)) .catch(() => setLoading(false)); }, [key, dispatch]); // 依赖加上key和dispatch,确保搜索词变化时重新请求 console.log(posts); // 放到组件顶层,每次渲染都能拿到最新的posts值 if (isLoading) { return <div>LOADING...</div> } if (!key) { return <div>PAGE DOES NOT EXIST</div> } else { return ( <Fragment> {posts.length > 0 ? ( <div className='postContainer'> {posts.map((post) => ( <div className='postitem' id='postitem' key={post.id}> <h2 id='postid'>{post.title}</h2> {post.text} </div> ))} </div> ) : ( <div>No results found</div> )} </Fragment> ) } }
另外要确认你的getPosts action是否正确处理异步请求,示例redux-thunk写法:
export const getPosts = (key) => async (dispatch) => { try { const res = await fetch(`你的接口地址?q=${key}`); const data = await res.json(); dispatch({ type: 'GET_POSTS_SUCCESS', payload: data }); } catch (err) { dispatch({ type: 'GET_POSTS_ERROR', payload: err }); } }
同时确保reducer正确处理GET_POSTS_SUCCESS action,把payload赋值给posts。
内容的提问来源于Stack Exchange,提问作者为匿名用户
相关产品推荐
相关产品推荐

