如何从三层嵌套子组件触发父组件API调用并更新参数word?
翻译后的用户提问
我希望实现以下需求:当位于三层嵌套结构中的子组件触发onClick事件时,更新父组件API调用中的参数word,从而触发API请求并获取响应。请问我需要使用Redux,还是可以用Context等其他状态管理方法实现?
此前我曾尝试使用Redux,但无法成功更新word的值;还尝试将API调用逻辑移至Redux Store中,却无法执行响应处理。相关代码如下:
function handleResponse(response) { setResult(response.data[0]); } function handlePexelsResponse(response) { setPhotos(response.data.photos); } function search() { let apiUrl = `https://api.dictionaryapi.dev/api/v2/entries/en/${word}`; axios.get(apiUrl).then(handleResponse); const pexelsApiKey = `563492ad6f91700001000001f8c251ed6a594872bacfe286e28414e4`; let pexelsUrl = `https://api.pexels.com/v1/search/?page=1&per_page=6&query=${word}`; let headers = { Authorization: `Bearer ${pexelsApiKey}` }; axios.get(pexelsUrl, { headers: headers }).then(handlePexelsResponse); } function handleSubmit(event) { event.preventDefault(); search(); } function wordSearched(event) { setWord(event.target.value); } if (loaded) { return ( <div className="dictionary"> <section> <form onSubmit={handleSubmit}> <input type="text" autoComplete="off" placeholder={props.suggestedSearch} onChange={wordSearched} /> </form> <div className="suggested-search"> suggested searches: forest, embroidery, stein, fascinator... </div> </section> <Result result={result} /> <Photos photos={photos} /> </div> ); } else { load(); return "loading..."; }
问题解答
结论:不需要Redux,用Props传递或Context即可
你的场景只是三层嵌套组件触发父组件的API请求,完全不需要Redux。Redux适合全局状态复杂、跨多个无关联组件共享状态的场景,这里用Props传递回调或者React Context就能轻松解决,前者更直接,后者适合不想逐层传参的情况。
两种可行实现方案
方案1:Props逐层传递回调函数
这是最简单直接的方式,把更新word和触发搜索的逻辑封装成回调,逐层传给最内层子组件,子组件点击时调用即可。
- 在父组件中定义回调函数:
// 父组件内 const updateWordAndSearch = (newWord) => { setWord(newWord); // 直接触发搜索,可根据需求加防抖等优化 search(); };
- 把这个函数通过props传给中间组件,中间组件再传给最内层子组件:
// 中间组件 const MiddleComponent = ({ updateWordAndSearch }) => { return <InnerComponent updateWordAndSearch={updateWordAndSearch} />; }; // 最内层子组件 const InnerComponent = ({ updateWordAndSearch }) => { return ( <button onClick={() => updateWordAndSearch("forest")}>搜索forest</button> ); };
方案2:React Context(适合层级更深的场景)
如果觉得逐层传props麻烦,可以用Context封装状态和操作方法,让所有需要的组件直接消费。
- 创建SearchContext:
import { createContext, useContext, useState } from 'react'; import axios from 'axios'; const SearchContext = createContext(); export const SearchProvider = ({ children }) => { const [word, setWord] = useState(""); const [result, setResult] = useState(null); const [photos, setPhotos] = useState([]); const handleResponse = (response) => { setResult(response.data[0]); }; const handlePexelsResponse = (response) => { setPhotos(response.data.photos); }; const search = () => { if (!word) return; const apiUrl = `https://api.dictionaryapi.dev/api/v2/entries/en/${word}`; axios.get(apiUrl).then(handleResponse); const pexelsApiKey = `563492ad6f91700001000001f8c251ed6a594872bacfe286e28414e4`; const pexelsUrl = `https://api.pexels.com/v1/search/?page=1&per_page=6&query=${word}`; const headers = { Authorization: `Bearer ${pexelsApiKey}` }; axios.get(pexelsUrl, { headers }).then(handlePexelsResponse); }; const updateWordAndSearch = (newWord) => { setWord(newWord); search(); }; return ( <SearchContext.Provider value={{ word, updateWordAndSearch }}> {children} </SearchContext.Provider> ); }; export const useSearch = () => useContext(SearchContext);
- 在父组件外层包裹
SearchProvider:
// 根组件或父组件外层 <SearchProvider> <Dictionary suggestedSearch="输入单词搜索..." /> </SearchProvider>
- 最内层子组件直接使用Context:
import { useSearch } from './SearchContext'; const InnerComponent = () => { const { updateWordAndSearch } = useSearch(); return ( <button onClick={() => updateWordAndSearch("embroidery")}>搜索embroidery</button> ); };
你之前Redux失败的可能原因
你用Redux没成功,大概率是这几个问题:
- Action或Reducer编写错误,没有正确更新
word状态; - 组件没有正确订阅Redux状态,导致更新后没重新渲染;
- 直接在Reducer里发API请求(Reducer必须是纯函数,异步逻辑需要用Thunk/Saga等中间件处理)。
但回到你的场景,完全没必要用Redux,上面两种方案足够解决问题。
内容的提问来源于stack exchange,提问作者user20257043
相关产品推荐
相关产品推荐

