@andrey_chirkin

Почему не обновляется state в дочернем компоненте?

Здравствуйте! Мне необходимо, чтобы при нажатии на ячейку таблицы границы выделялись синим цветом, как в google sheets. Я разделил код. Каждая ячейка строки рендерится с помощью дочернего компонента. Но при обновлении в нем стейта stateClick перерендер не происходит, и выделение с ячейки не снимается.

import React, {useEffect, useState} from 'react'
import TableCell from './Components/TableCell.js'

export default function OperationTable() {

    const [dataCell, setDataCell] = useState([
            {
                FirstName: 'Ivan',
                SurName: 'Ivanov',
                Age: 22,
                Car: 'Mazda 3'
            },
            {
                FirstName: 'Semen',
                SurName: 'Semenov',
                Age: 22,
                Car: 'Ford Focus 3'
            }
        ]
    )

    return (
        <div className="operationTable">
            <table>
                <thead>
                <tr>
                    <WidthColumns
                        classNameHeader="FirstName"
                        NameHeader="FirstName"
                        classNameDiv="resizer"
                        id="FirstName"
                    />
                    <WidthColumns
                        classNameHeader="SurName"
                        NameHeader="SurName"
                        classNameDiv="resizer"
                        id="SurName"
                    />
                    <WidthColumns
                        classNameHeader="Age"
                        NameHeader="Age"
                        classNameDiv="resizer"
                        id="Age"
                    />
                    <WidthColumns
                        classNameHeader="Car"
                        NameHeader="Car"
                        classNameDiv="resizer"
                        id="Car"
                    />
                </tr>
                </thead>
                <tbody>
                {dataCell.map((item, index) => (
                    <tr key={index}>
                        <TableCell index={index} name="FirstName" state={dataCell}/>
                        <TableCell index={index} name="SurName" state={dataCell}/>
                        <TableCell index={index} name="Age" state={dataCell}/>
                        <TableCell index={index} name="Car" state={dataCell}/>
                    </tr>
                ))}
                </tbody>
            </table>
        </div>
    )
}

import React, {useEffect, useState} from 'react'

const TableCell = ({index, name, state}) => {

	const [dataTable, setDataTable] = useState(state)

	//--------------------------------------------------------------------------

	let copyDataTable = JSON.parse(JSON.stringify(dataTable))
	let initialClickData = copyDataTable.map(item => {
		for (let el in item) {
			item[el] = false
		}
		return item
	})

	const [stateClick, setStateClick] = useState(initialClickData)

	//--------------------------------------------------------------------------

	const handleClick = (index, name) => (
		() => {
			console.log(initialClickData[index][name])
			initialClickData[index][name] = !initialClickData[index][name]
			console.log(initialClickData[index][name])
			setStateClick(initialClickData)
		}
	)

	useEffect(() => {
		console.log(stateClick)
	}, [stateClick])

	return (
		<>
			<td
				name={name}
				onClick={handleClick(index, name)}
				style={stateClick[index][name] ? {
					outline: '2px solid blue',
					outlineOffset: '-1px',
					position: 'relative'
				} : {border: '1px solid #c7c7c7'}}
			>
				<div className={name + "Cell"}>
					{dataTable[index][name]}
				</div>
				<span className={name}> </span>
			</td>
		</>
	)
}

export default TableCell
  • Вопрос задан
  • 208 просмотров
Пригласить эксперта
Ответы на вопрос 1
insighter
@insighter
-First time? - Huh? (C#, React, JS)
Вы выделяете ячейку по которой щелкаете, но состояние предыдущей выделенной ячейки не меняется.

1. Плохой вариант. Уведомляйте родителя о том, что выделяется ячейка и путь он хранит состояние какая ячейка/строка выделены.
// передавайте обработчик onClick ребенку и в него же передавайте статус ячейки
const TableCell = ({index, name, state, onClick}) => {...}

2. Хороший вариант. Вместо этого. лучше и onClick реализовать на уровне родительской таблицы, а не на каждую ячейку вешать обработчик события, это жутко неоптимально.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы