在React Hooks中使用带有Set状态的Dynamic Var吗?

时间:2019-02-13 21:44:51

标签: javascript reactjs react-hooks

这是React组件中非常常见的模式:

handleTextFieldChange(event)
{
    const name = event.currentTarget.name;
    this.setState({[name]: event.currentTarget.value})
}

React钩子可以使用哪种Java语法来实现相同功能?

即可能类似于:

handleTextFieldChange(event)
{
    const name = event.currentTarget.name;
    this.set[name](event.currentTarget.value);
}

6 个答案:

答案 0 :(得分:7)

您可以使用单个useState,其默认值是包含所有输入值的对象,并像使用类组件那样对其进行更新。

示例

const { useState } = React;

function App() {
  const [state, setState] = useState({ email: "", password: "" });
  function onChange(event) {
    const { name, value } = event.target;
    setState(prevState => ({ ...prevState, [name]: value }));
  }

  return (
    <div>
      <input value={state.email} name="email" onChange={onChange} />
      <input value={state.password} name="password" onChange={onChange} />
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>

答案 1 :(得分:3)

这样的事情怎么样?

function handleTextFieldChange(mySetFunction, event) {
    const value = event.currentTarget.value;
    mySetFunction(value);
}

<TextField
    placeholder="Email"
    name="passwordResetEmailAddress"
    onChange={(e) => handleTextFieldChange(setPasswordResetEmailAddress, e)}
>
    {passwordResetEmailAddress}
</TextField>

我已经对其进行了测试,并且可以正常工作。

答案 2 :(得分:1)

我最近在将组件从类转换为函数时解决了同样的问题。我最终创建了一个对象,该对象然后可以指向单独的状态挂钩:

const textStates = {};
const setTextStates= {};
for (var name of names) {
  let [textState, setTextState] = useState("");
  textStates[name] = textState;
  setTextStates[name] = setTextState;
}

答案 3 :(得分:1)

您可以通过在onChange函数中接收更新状态函数作为参数来动态更新目标字段的状态。

示例

import React, { useState } from "react";

const App = () => {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");

  const onChangeHandler = (setIdentifierState, event) => {
    setIdentifierState(event.target.value);
  };

  return (
    <div>
      <p>{"Email: " + email}</p>
      <p>{"Password: " + password}</p>
      <input
        type="text"
        placeholder="email"
        onChange={onChangeHandler.bind(this, setEmail)}
      />
      <input
        type="text"
        placeholder="password"
        onChange={onChangeHandler.bind(this, setPassword)}
      />
    </div>
  );
};

export default App;



答案 4 :(得分:0)

class Yup extends React.Component {
  state = {
    first: "",
    second: ""
  };

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

  render() {
    const { first, second } = this.state;
    return (
      <div>
        <p>{first}</p>
        <p>{second}</p>
        <input type="text" name="first" onChange={this.handleTextFieldChange} />
        <input
          type="text"
          name="second"
          onChange={this.handleTextFieldChange}
        />
      </div>
    );
  }
}

与钩子相同

function Yup() {
  const [{ first, second }, setState] = useState({ first: "", second: "" });

  function handleTextFieldChange({ target: { name, value } }) {
    setState(prevState => ({ ...prevState, [name]: value }));
  }

  return (
    <div>
      <p>{first}</p>
      <p>{second}</p>
      <input type="text" name="first" onChange={handleTextFieldChange} />
      <input type="text" name="second" onChange={handleTextFieldChange} />
    </div>
  );
}

答案 5 :(得分:0)

我是这样解决的(比@VikR 提供的解决方案稍微动态一点)

const [title, setTitle] = useState("");
const [desc, setDesc] = useState("");
const [video, setVideo] = useState("");

const handleChange = setter => event => {
    const value = event.target.value;
    //special cases
    if (setter === setVideo) {
        setInvalidVideo(!ReactPlayer.canPlay(value))
    }

    setter(value)
}

然后在我的代码中:

        <TextField fullWidth value={title} type="date"
                   label={t('service.ticket.add.title')}
                   placeholder={t('service.ticket.add.titlePh')}
                   onChange={handleChange(setTitle)} variant="outlined"/>