使用useState在React组件之间传递值

时间:2019-11-30 12:39:51

标签: react-hooks

我使用带有Apollo客户端的React组件作为功能组件。我的主要搜索组件的功能主体如下所示:

function SearchContainer(props) {
    const [begTime, setBegTime] = useState('')

    const runSearch(begin_time) {
        console.log('begin_time: ', begin_time) <== The printed value is Ok!
        setBegTime(begin_time) <=== Use hook to set the value of begTime
        console.log('begTime: ', begTime)  <=== The output shows no change in begTime. Why?
    }

    return (
// Use SearchForm to get the search parameters.
        <SearchForm 
          handleSearch={runSearch} <== Use SearchForm to get begin_time back into this component.
        />       
// Provide the parameters from SearchForm and run the useQuery from Apollo using this parameters.
        <SearchResults
          begTime={begTime}
        />
    )
}

SearchForm只是带有ReactState钩子的React函数组件的常规形式,并且对表单的调用都提交了hanldeSearch函数。

function SearchForm({handleSearch}) { <== handleSearch function from the parent component.
   const handleSubmit = (begin_time) => {
       handleSearch(begin_time) <== This call works and the value will be provided to the parent.
   } 
...
}

我对这段代码的想法是创建2个独立的组件。一个组件(SearchForm)应该获取参数。另一个组件(SearchResults)将获得此参数作为参数,使用useQuery运行查询并显示结果。

但是在我的情况下,useState挂钩不能很好地工作。有趣的是,如果我两次调用相应的搜索表单,可以在runSearch函数中看到begTime具有先前的搜索值,而不是初始值。因此,显然useState可以工作,但是我想使用当前值而不是先前的值来运行搜索。

是否可以使用React钩子创建此类组件?这是我的第一个使用钩子而不是类的大型测试。

预先感谢

安德烈(Andrej)

1 个答案:

答案 0 :(得分:0)

您的问题

const runSearch(begin_time) {
        console.log('begin_time: ', begin_time) 
        setBegTime(begin_time) 
        console.log('begTime: ', begTime)  <=== The output shows no change in begTime. Why?
    }

输出显示begTime没有变化。为什么? 正如文档中所述,当我们设置状态为异步功能时。
我的意思是您的代码将继续运行,并且要设置状态react将在另一个线程上启动子进程。并在完成后将结果传递给主线程。 (您可以在useEffect或componentDidUpdate中获得早期版本)。
所以要点是

  1. 在setBegTime(begin_time)异步过程开始
  2. 主线程中的代码不会等待
  3. 因此,处理下一个语句console.log('begTime: ', begTime)时,您没有看到任何更改,因为实际上它的值尚未更新。 React仍在更新价值。


更新过程是异步的,因为React不想让主线程等待繁重的工作(更新状态是繁重的过程),就好像它等待那么网页将不会响应直到完成。因此,它改为在另一个线程上运行该进程。
对于第二个
你可以试试这个

function SearchContainer(props) {
    const [begTime, setBegTime] = useState('')
    const [response,setResponse] = useState({})
    useEffect(()=>{
    const runSearch = (begin_time) {
        setBegTime(begin_time) 
    }
},[begin_time])

// u can rather define working of handleSubmit in parent component and <br/>
// store its output in state and then pass it to another component
const handleSubmit = (begin_time) => {
       resp = handleSearch(begin_time)
       setResponse(resp)
   } 
        return (
    // Use SearchForm to get the search parameters.
            <SearchForm 
              handleSearch={()=>handleSubmit()}
            />       
    // Provide the parameters from SearchForm and run the useQuery from Apollo using this parameters.
            <SearchResults
              begTime={begTime}
              response={response}
            />
        )
    }