Answer the question
In order to leave comments, you need to log in
Why doesn't React render the component on state change?
The UserTable file has an addRow function that changes the variable responsible for the number of rows in the table, but after setting a new state, rendering does not occur, and the variable itself changes only after the second click on the button that calls this function. I don't understand how to fix this.
usertable:
import React, {Component} from 'react'
import MocData from '../../MocData.json'
import Table from '../../components/Table/Table'
export default class UsersTable extends Component {
constructor(props) {
super(props)
this.state = {
data: MocData,
numberOfRows: MocData.length,
}
}
addRow = (event) => {
let numberOfRows = this.state.numberOfRows + 1
this.setState({
numberOfRows
})
console.log(this.state.numberOfRows)
}
render() {
let tableButtons = [
{
content: 'Сохранить таблицу',
title: null,
type: 'save'
},
{
content: 'Добавить запись',
title: null,
type: 'add',
onClickHandler: this.addRow
}
]
return (
<Table
numberOfRows = {this.state.numberOfRows}
numberOfColumns = {Object.keys(this.state.data[0].data).length}
columnNames = {Object.keys(this.state.data[0].data)}
content = {this.state.data}
tableButtons = {tableButtons}
/>
)
}
}
import React, {Component} from 'react'
import './Table.scss'
import Row from './Parts/Row'
import Button from '../Button/Button'
export default class Table extends Component {
constructor(props) {
super(props)
this.state = {
numberOfRows: props.numberOfRows, // Число от 0
numberOfColumns: props.numberOfColumns, // Число от 0
columnNames: props.columnNames, // Массив строк, например ['Имя1','Имя2']
content: props.content, // Массив объектов, каждый из которых содержит id и объект data | { id: 1234, data: {name: 'Иван', surname:'Иванов'}}
tableButtons: props.tableButtons, // Массив объектов с параметрами кнопок, где каждый объект содержит параметры конкретной кнопки
rowButtons: []
}
}
createButtons = (tableButtons) => {
let Buttons = []
tableButtons.map( (item, index) => {
Buttons.push(
<Button
key = {tableButtons[index].content}
title = {tableButtons[index].title}
type = {tableButtons[index].type}
onClick = {tableButtons[index].onClickHandler}
>
{tableButtons[index].content}
</Button>
)
})
return Buttons
}
createRow = (counter, content, isHeader = false) => {
let rows = []
for (let i = 0; i < counter; i++) {
if (isHeader) {
rows.push(
<Row
key = {counter}
numberOfColumns = {this.state.numberOfColumns}
content = {content}
isHeader = {isHeader}
/>)
} else if (content[i]){
rows.push(
<Row
key = {content[i]._id}
id = {content[i]._id}
numberOfColumns = {this.state.numberOfColumns}
content = {content[i].data}
isHeader = {isHeader}
/>)
} else {
rows.push(
<Row
key = {counter + 1}
numberOfColumns = {this.state.numberOfColumns}
content = {null}
isHeader = {isHeader}
/>)
}
}
return (rows)
}
render() {
return (
<React.Fragment>
<table className="Table">
<tbody>
{this.createRow(1, this.state.columnNames, true)}
{this.createRow(this.state.numberOfRows, this.state.content)}
</tbody>
</table>
<div className="buttonContainer">
{this.createButtons(this.state.tableButtons)}
</div>
</React.Fragment>
)
}
}
import React from 'react'
import './Button.scss'
const Button = props => {
const cls = `Button ${props.type}`
return (
<button
className={cls}
type="button"
onClick={props.onClick}
title={props.title}
>
<span>{props.children}</span>
</button>
)
}
export default Button
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question