React hook useState. Каким образом можно навесить хук на неизвестное количество элементов, при использовании map
Создаю приложение в котором получаю данные с базы, количество данных заранее неизвестно. Необходимо каким то образом навесить на каждый элемент списка хук useState для дальнейшей работы с каждым элементом (по отдельности). Пример кода.
const [BtnNameUser, setBtnNameUser] = useState();
const List_vm = ({vm_list}) => {
const listItems = vm_list.map(vm => {
return(
<div>
<p>{Object.keys(vm)[0]}</p>
<input type="button" value={BtnNameUser} onClick={() => btn_click(Object.keys(vm)[0])}/>
</div>
);
});
return (<div>{listItems}</div>);
}
Если я делаю таким образом, значение ставиться для всех элементов одно и тоже. Буду благодарен любой помощи.
Ответы (2 шт):
При использовании map необходимо возвращать компонент, а внутри этого компонента можно создать любое количество хуков. Примерно так:
// import React from "react";
const data = [
{ id: 1, title: "Title1", userName: "User1" },
{ id: 2, title: "Title2", userName: "User2" },
{ id: 3, title: "Title3", userName: "User3" },
{ id: 4, title: "Title4", userName: "User4" },
];
const App = () => {
return (
<div>
<ListVm vm_list={data} />
</div>
);
};
// export default App;
const ListVm = ({ vm_list }) => {
return (
<div>
{vm_list.map((item) => (
<ItemComponent item={item} key={item.id} />
))}
</div>
);
};
const ItemComponent = ({ item }) => {
const [btnNameUser, setBtnNameUser] = React.useState(item.userName);
return (
<div>
<p>{item.title}</p>
<input
type="input"
value={btnNameUser}
onChange={({ target: { value } }) => setBtnNameUser(value)}
/>
</div>
);
};
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Создать отдельный компонент для каждого шага. Сразу скажу не уверен хороший ли это подход, но он работает
Компонент с div
export function DivElement(props) {
const [btnUser, setBtnUser] = useState(props.btnUser)
return (
<div>
<p>{props.keysVM}</p>
<input
type="button"
value={btnUser}
onClick={() => btn_click(props.keysVM)}
/>
</div>
);
}
И пробежаться map
import {DivElement} from ---blablabla----
const listItems = vm_list.map((vm) => {
return <DivElement btnUser={BtnNameUser} keysVM={Object.keys(vm)[0]} />;
});
Примерно так, код не тестировал, но идея должна быть ясна