【问题标题】:React Hooks: paradigm transition problem from sync to asyncReact Hooks:从同步到异步的范式转换问题
【发布时间】:2020-04-05 18:54:30
【问题描述】:

我刚开始使用 React 钩子,但遇到了问题。在下面的组件中,我通过 react 钩子更新了一个值,并将其用作函数的参数。问题是钩子是异步的,所以当我调用函数时,值是未定义的。 代码如下:

反应钩子:

const [selectedLocation, setSelectedLocation] = React.useState()

我需要更新selectedLocation的函数:

  const sendLocationToDevice = (loader = true) => {
    props.dispatch({type: "CLEAR_ERROR"})
    const resObj = CalculateBearing({
      a: {lat: props.store.position.latitude, long: props.store.position.longitude},
      b: {lat: selectedLocation.coordinates.lat, long: selectedLocation.coordinates.lng} // -> here's the value is undefined
    })

我更新selectedLocation值的表单:

          <View>
          { selectedLocation === null ? (
            <GooglePlacesAutocomplete
              placeholder='Enter Location'
              minLength={2}
              autoFocus={false}
              returnKeyType={'default'}
              fetchDetails={true}
              onPress={(data, details = null) => {
                setSelectedLocation({name: details.formatted_address, coordinates: details.geometry.location})
                sendLocationToDevice()
              }}

流程是:用户使用表格选择位置并调用函数计算方位。使用旧的 this.setState 一切都是同步的,所以我没有问题,现在我不确定最好的模式是什么,或者我是否误用了钩子......我应该如何解决这个问题?

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    您可以使用React.useEffect 挂钩来监听selectedLocation 状态的变化,然后在那里调用sendLocationToDevice

    例如,

    function MyComponent() {
      const [selectedLocation, setSelectedLocation] = React.useState(null)
    
      React.useEffect(() => {
        if (selectedLocation === null) return
    
        function sendLocationToDevice() {
          // ...
        }
        sendLocationToDevice()
      }, [selectedLocation])
    
      return (
        <GooglePlacesAutocomplete 
          onPress={(data, details = null) =>
            setSelectedLocation({
              name: details.formatted_address, 
              coordinates: details.geometry.location})
            })
          }
        />
      )
    }
    

    React.useEffect 内部的回调将始终在 selectedLocation 更改时调用,并且它将具有 selectedLocation 的最新值。


    编辑:

    作为替代方案,您可以将回调传递给setSelectedLocation,并在其中调用其他函数。唯一的缺点是您将不再使用您的state,因此这可能会或可能不会导致问题。

    function MyComponent() {
      const [selectedLocation, setSelectedLocation] = React.useState(null)
    
      function sendLocationToDevice(locationData) {
        // ...
      }
    
      return (
        <GooglePlacesAutocomplete 
          onPress={(data, details = null) => {
            const locationData = {
              name: details.formatted_address,
              coordinates: details.geometry.location
            }
            sendLocationToDevice(locationData)
            return locationData // updates state
          }}
        />
      )
    }
    

    但是,我认为第一个解决方案更简洁更好,所以我会选择 useEffect 钩子。

    【讨论】:

    • 酷,它有效,所以作为一般规则,我应该创建一个 useEffect 函数来观察状态的变化并从那里获取它?
    • @ste 查看我的编辑,但在我看来,在这种情况下,最好的方法是使用 React.useEffect 钩子。
    猜你喜欢
    • 2021-06-02
    • 2021-12-13
    • 2018-12-09
    • 2011-09-07
    • 1970-01-01
    • 1970-01-01
    • 2014-05-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多