如何在基于类的组件中正确转换状态以使用Hooks?

时间:2019-12-04 10:17:10

标签: reactjs react-hooks

我在表单输入字段中不断得到[object Object]

我一直在尝试使用useState()钩子更改多个元素的状态,但是正在努力将所有元素都放在同一个切换函数中。以前我有

state = {
  username: "Hunter",
  location: "",
  name: "",
  date: "today"
};

toggleAll = e => {
  const { name, value } = e.target;
  this.setState({ [name]: value });
};

这很好。当我尝试将其转换为Hooks时

 const [username, setUsername] = useState("Hunter")
 const [location, setLocation] = useState("") 
 const [name, setName] = useState("") 
 const [date, setDate] = useState("today") 

并以这种方式更新

function toggleAll(e) {
        const {name, value} = e.target 
        name === "location" ? setLocation({ [name]: value }) : 
        name === "name" ? setName({ [name]: value }) :
        name === "date" ? setDate({ [name]: value }) :
        setUsername({ [name]: value }) 
    }

这行不通。在表单的输入字段中,编写时得到[object Object]。单选按钮不能正常工作。

2 个答案:

答案 0 :(得分:4)

您的状态值不再是对象,因此您只需要设置value

function toggleAll(e) {
        const {name, value} = e.target 
        name === "location" ? setLocation( value ) : 
        name === "name" ? setName( value ) :
        name === "date" ? setDate( value ) :
        setUsername( value ) 
    }

这似乎是useReducer钩子作为useState的替代品的好用例。

使用reducer钩子的优点是,通常在应用程序具有复杂状态且与您之前拥有的状态结构更相似时,通常建议使用它。此外,如果您的操作类型名称和输入名称一致toggleAll函数将更加简单。基本实现可能如下所示:

const initialState = {
  username: "Hunter",
  location: "",
  name: "",
  date: "today"
};

const reducer = (state, action) => {
  switch (action.type) {
    case "SET_USERNAME":
      return {
        ...state,
        username: action.payload
      };

    case "SET_LOCATION":
      return {
        ...state,
        location: action.payload
      };
    case "SET_NAME":
      return {
        ...state,
        name: action.payload
      };
    case "SET_DATE":
      return {
        ...state,
        name: action.payload
      };
  }
};


// Inside component 

const [state, dispatch] = useReducer(reducer, initialState);

function toggleAll(e) {
  const { name, value } = e.target;
  const actionType = `SET_${name.toUpperCase()}`;
  dispatch({ type: actionType, payload: value });
}

答案 1 :(得分:0)

设置状态的语法有问题,与类组件的setState相比,它不再像这样。 只需执行以下操作即可:

function toggleAll(e) {
        const {name, value} = e.target 
        name === "location" ? setLocation(value) : 
        name === "name" ? setName(value) :
        name === "date" ? setDate(value) :
        setUsername(value) 
    }