React Hooks动态输入

时间:2019-03-18 22:12:56

标签: javascript reactjs typescript

我有一个form component,您可以在其中单击按钮添加输入,创建一个新团队,并在其中添加球员。

问题是,如果您输入一个值,则所有输入都将被该值填充,因为它使用的是相同状态。我的猜测是为每个新团队创建一个新的状态值(类似于“输入” +索引,这将导致输入0,输入1,输入2等状态)。

尽管我无法使用React Hooks来实现此功能,因为您必须首先声明状态并为其分配一个set函数。

是否考虑过如何实现这种行为?

3 个答案:

答案 0 :(得分:5)

这只是一个非常简单的解决方案,它跟踪数组中的值,只是为了说明钩子并没有增加任何难度:

function App() {
  let [inputs, setInputs] = useState([""]);

  return (
    <div className="App">
      <button onClick={() => setInputs(inputs.concat(""))}>Add input</button>
      <form>
        {inputs.map((value, i) => (
          <div key={i}>
            <label>Input {i + 1}</label>
            <input
              value={value}
              onChange={e =>
                setInputs(
                  inputs.map((value, j) => {
                    if (i === j) value = e.target.value;
                    return value;
                  })
                )
              }
            />
          </div>
        ))}
      </form>
    </div>
  );
}

codesandbox

答案 1 :(得分:1)

将您的状态构造为:

const teams = [
  { name: "Team 1", players: [ /* ... */ ] },
  { name: "Team 2", players: [ /* ... */ ] },
  /* ... */ 
]; 

我建议您使用useReducer()钩子,它非常适合您的情况!它有点笨拙,但是具有干净且易于理解的代码。

function reducer(state, action) {
  switch (action.type) {
    case 'addPlayer':
      // find needed team and push player object there
    case 'addTeam':
      // push new team object into state
    default:
      throw new Error();
  }
}

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

状态结构可能会有所不同,例如,您可以将键对象用于团队无关紧要。

答案 2 :(得分:-1)

我将这样构造状态:

// initial state
state = { teams: [] }

其中每个团队对象都有一个名称,并具有一组玩家:

{ name: "team1", players: ["player1", "player2"] }

所以状态可能最终看起来像这样:

{ teams: [
  { name: "team1", players: ["player1", "player2"] },
  { name: "team2", players: ["player3", "player4"] },
  { name: "team3", players: ["player5", "player6"] }
  ]
}