【问题标题】:React Hooks dynamic inputReact Hooks 动态输入
【发布时间】:2019-03-18 22:12:55
【问题描述】:
我有一个form component,您可以在其中单击按钮添加输入,创建一个新团队,您可以在其中添加球员。
问题是,如果您填写一个值,所有输入都将填充该值,因为它使用的是相同的状态。我的猜测是为每个新团队创建一个新的状态值(例如“输入”+索引,这将导致输入 0、输入 1、输入 2 等状态)。
虽然我无法使用 React Hooks 实现这一点,因为您必须首先声明您的状态,并为其分配一个 set 函数。
有没有想过如何实现这种行为?
【问题讨论】:
标签:
javascript
reactjs
typescript
【解决方案1】:
这只是一个非常简单的解决方案,跟踪数组中的值,只是为了说明钩子不会让任何事情变得更困难:
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
【解决方案2】:
将您的状态构建为:
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);
状态结构可能会有所不同,例如,您可以对无关紧要的团队使用键控对象。
【解决方案3】:
我会这样构建状态:
// 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"] }
]
}