React组件的props的Redux存储状态不反映Redux存储的状态值

时间:2020-09-12 07:22:59

标签: javascript reactjs forms redux react-redux

我有一个具有3个输入字段和一个按钮的react组件。
该组件已连接到Redux存储。
有一个动作创建者可以进行Web API调用,以获取用户的位置信息并更改redux存储中的状态。
表单中按钮的onClick事件具有一个handleOnClick处理函数,该处理函数调用操作以更新商店的状态,然后调用setFormData将输入字段中的值更新为更改输入字段的值。

import React, {useState} from 'react';
import {connect} from 'react-redux';
import {setLocation} from "../actions/location.js";

const LocationForm = ({location, setLocation}) => {
  
  const [formData, setFormData] = useState({
    city:"",
    state:"",
    country:""
  })
  
  const handleOnChange = (e) => {
    setFormData({...formData, [e.target.name]:e.target.value})
  }
  
  const handleOnClick = () => {
    setLocation();
    console.log(location) //!! output: {city:"", state:"", country:""}
    const {city, state, location} = location;
    setFormData({...formData, city, state, location})
  }

  const {city, state, country} = formData;

  return (
    <form>
      <button onClick={handleOnClick}/>
      <label>
        City:
        <input name="city" value={city} onChange={handleOnChange}/>
      </label>
      <label>
        State:
        <input name="state" value={state} onChange={handleOnChange}/>
      </label>
      <label>
        Country:
        <input name="city" value={country} onChange={handleOnChange}/>
      </label>
    </form>
  )
}

const mapStateToProps = (state) => {
  location: state.location
}

export default connect(mapStateToProps, {setLocation})(LocationForm);

问题:console.log()中的handleOnClick可以看出,从redux存储向下传递的location对象的状态仍然具有空字符串作为键的值(城市,州,国家)。但是redux chrome devtool中的状态确实显示位置状态已更改,并且它们具有正确的值。 组件道具中的位置对象为什么不能反映出来?我是否需要使用useEffect钩子来更新组件道具中的location对象?

谢谢。

2 个答案:

答案 0 :(得分:2)

如果要监视location属性的更改,则必须使用一个钩子,下面是一个示例:

import React, {useState, useEffect} from 'react';
import {connect} from 'react-redux';
import {setLocation} from "../actions/location.js";

const LocationForm = ({location}) => {
  
  ..
  
  useEffect(() => {
    console.log(location)
    const {city, state, location} = location;
    setFormData({...formData, city, state, location})
  }, [location]);
  
  const handleOnClick = () => {
    setLocation();
  }

  ..
}

每次作为第二个参数传递的数组的任何元素发生变化时,都会调用作为第一个参数传递给useEffect的函数。

在这里,每次location更改时,就会使用setFormData中的新值来调用location

答案 1 :(得分:0)

您正在将mapDispatchToProps匿名对象传递给connect,但未在组件中使用它。取而代之的是,您将setLocation()作为普通函数调用而没有调度。您需要调用prop,而不是像这样的导入函数:

const LocationForm = ({location, setLocation}) => {
    ...
      setLocation()
    ...

export default connect(mapStateToProps, {setLocation})(LocationForm);

我还建议给钩子一个机会,它可能更容易理解恕我直言:
import {useSelector, useDispatch} from 'react-redux'
...

const LocationForm = () => {
  const location = useSelector((state) => state.location)
  const dispatch = useDispatch()
  ...
  
  const handleOnClick => {
    dispatch(setLocation)      // if setLocation = (dispatch) => ...
    // dispatch(setLocation()) // if setLocation = () => (dispatch) => 
    ...