Изменение cостояния конкретной кнопки по нажатию. ReactJS
читатель! Ниже предоставлю отрывки кода для большей ясности.
Ниже в стейте хранятся некоторые свойства, которые будут упоминаться дальше.
state = {
dataArr: [], // Массив полученых данных с сервера
divShow: false,
name: '',
age: '',
email: '',
btnEditShow: true,
// btnSaveShow: false,
idData: '',
// btnEditBool: true
};
Здесь представлен весь фрагмент рендеринга и тут же имеется проблема, которую я опишу ниже(после кода).
render() {
const { dataArr, divShow, btnEditShow, btnSaveShow, btnEditBool } = this.state
return (
<div className='containerTableBack' >
<table className="table tableBack" border="1">
<caption>Here is data backEnd:</caption>
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>Email</th>
</tr>
</thead>
<tbody>
{dataArr.map(e => {
return ( <tr key={e}><td>{e.data.name}</td><td>{e.data.age}</td><td>{e.data.email}</td>
<td> <button
key={e}
id={e._id}
className={btnEditShow ? '' : 'btnEditShow'}
// style={btnEditShow ? {} : { display: 'none' }}
onClick={this.btnShowEditInputs}
>Edit</button></td>
<button
id={e._id}
onClick={this.deleteData}
>Delete</button> </tr>
);
})}
</tbody>
</table>
<div className={`newData-Div ${!divShow ? 'displayDivNone' : ''} `} >
<input placeholder="Name" type='text' onChange={this.nameHandleChange} />
<input placeholder="Age" type='number' onChange={this.ageHandleChange} />
<input placeholder="Email" type='text' onChange={this.emailHandleChange} />
<button onClick={this.addNoteOnPage} >Add Note</button>
</div>
<button onClick={this.addNewData} >Add Note</button>
</div>
);
}
Функция, которая используется:
btnShowEditInputs = (e) => {
this.setState({ btnEditShow: false })
}
Ниже фрагмет с проблемой:
{dataArr.map(e => {
return (
<tr key={e}><td>{e.data.name}</td><td>{e.data.age}</td><td>{e.data.email}</td>
<td> <button
key={e}
id={e._id}
className={btnEditShow ? '' : 'btnEditShow'}
// style={btnEditShow ? {} : { display: 'none' }}
onClick={this.btnShowEditInputs}
>Edit</button></td>
<button
id={e._id}
onClick={this.deleteData}
>Delete</button> </tr>
);
Сама суть проблемы заключается в следующем. Отрисовывается таблица, т.е. первый компонент(куда входят данные, кнопка edit и delete), второй и последующие компоненты так же с данными и кнопками. Как с помощью стейтов или других способов можно сделать так, при нажатии на кнопку Edit она скрывалась и появлялась кнопка Save? Делал много разных способов, но всегда при нажатии на Edit у меня все кнопки из Edit скрывались, а Save появлялись, а мне нужно только на одной компоненте это сделать.
Ответы (1 шт):
Вам можно вынести строку таблицы в отдельный компонент, со своим стейтом, например:
const TableRow = ({ name, age, email, onEdit, onDelete, onSave }) => {
const [ isEdit, setIsEdit ] = useState(false);
const handlerClickEdit = useCallback(() => {
setIsEdit(true);
onEdit();
}, [ onEdit ]);
const handlerClickSave = useCallback(() => {
setIsEdit(true);
onSave();
}, [ onSave ]);
return (
<tr>
<td>{ name }</td>
<td>{ age }</td>
<td>{ email }</td>
<td>
{!isEdit && (
<button onClick={ handlerClickEdit }>
Edit
</button>
)}
{isEdit && (
<button onClick={ handlerClickSave }>
Save
</button>
)}
</td>
<button
onClick={ onDelete }
>Delete
</button>
</tr>
);
}
const Table = () => {
const data = [ { id: 1, name: 'Test' } ];
return (
<table>
{ data.map((item) => (
<TableRow
key={item.id}
name={item.name}
age={null}
email={null}
onEdit={() => null}
onDelete={() => null}
onSave={() => null}
/>
))}
</table>
)
}
Или хранить в state не флаг, а id записи и при рендере проверять на редактирование. Например:
class Component {
state = {
data: [ {id: 1, name: 'Test' }],
editId: null,
}
handlerClickEdit = (rowId) => (e) => {
this.setState({ editId: rowId });
}
handlerClickSave = (rowId) => (e) => {
this.setState({ editId: null });
}
render() {
const { editId } = this.state;
return (
<table>
{data.map((item) => (
<tr key={item.id}>
<td>{ name }</td>
<td>
{item.id === editId && (
<button onClick={this.handlerClickSave(item.id)}>
Save
</button>
)}
{item.id !== editId && (
<button onClick={this.handlerClickEdit(item.id)}>
Edit
</button>
)}
</td>
</tr>
))}
<table/>
)
}
}
Если есть возможность редактировать сразу несколько записей, то в editId должен быть массив и проверка на вхождение item.id в него.