VGVolkov
@VGVolkov
самоучка

Почему не рефакторится компонент?

Задача лист TODO. В общем, если хочу создать новый пункт списка, то он обновляется только после любых других операций (удаление, смета статуса):
class App extends React.Component {
        constructor() {
            super();
            this.state= {
                tasks: [
                    {name: 'Присесть 10 раз', status: false},
                    {name: 'Присесть 1280 раз', status: false},
                    {name: 'Присесть 180 раз', status: false},
                    {name: 'Прочитать 20 стр.', status: false}
                ]
            }
        }

        deleteItem(num) {
            this.state.tasks.splice(num.i, 1); //удаляю указанный пункт
            this.setState({tasks: this.state.tasks}); //изменяю стэйт
            //console.log("Del" + this.state.tasks);;
            console.log(num.i);
        }

        changeStatus(num) {
            this.state.tasks[num.i].status=!this.state.tasks[num.i].status; //меняю статус на противоположный
            this.setState({tasks: this.state.tasks}); //изменяю стейт
            console.log(this.state.tasks);

        }

        createItem(task) {
            console.log(task);
            this.state.tasks.unshift({name: task, status: false});
            this.setState({tasks: this.state.tasks});
            console.log(this.state.tasks);


        }

        render() {
            return <div>
                <CreateItem
                    createItem={this.createItem.bind(this)}
                />
                <br />
                <TableItem
                    tasks={this.state.tasks}
                    deleteItem={this.deleteItem.bind(this)}
                    changeStatus={this.changeStatus.bind(this)}
                />
            </div>;
        }
    }


    class CreateItem extends  React.Component {
        constructor(props) {
            super(props);
            this.state= {item:''}
        }

        handleChange(event) { //делаю двустороннюю зависимость, чтобы менялось содержимое input
            this.setState({item: event.target.value});
        }

        handleButton() {
            this.props.createItem(this.state.item);
            this.setState({item: ''});
            
        }

        render() {
            return <div>
                <input onChange={this.handleChange.bind(this)} value={this.state.item}/>
                <button onClick={this.handleButton.bind(this)}>create</button>
            </div>

        }
    }

    class TableItem extends  React.Component {
        constructor(props) {
            super(props);
            this.point = '';
            this.list = {};

            this.state = {
                list: this.props.tasks.map((e, i) => {
                    const status = e.status ? 'green' : 'red';

                    return <tr key={i}>
                        <td onClick={this.myChangeStatus.bind(this, {i})} style={{color: status}}>{e.name}</td>
                        <td>
                            <button onClick={this.myDeleteItem.bind(this, {i})}>delete</button>
                            <button onClick={this.makeList.bind(this, {i})}>edit</button>
                        </td>
                    </tr>;
                })
            }
            ;


        }

        myChangeStatus(num) {

            this.props.changeStatus.bind(null, num)();

            this.setState({
                list: this.props.tasks.map((e, i) => {

                    const status = e.status ? 'green' : 'red';

                    return <tr key={i}>
                        <td onClick={this.myChangeStatus.bind(this,{i})} style={{color: status}}>{e.name}</td>
                        <td>
                            <button onClick={this.myDeleteItem.bind(this, {i})}>delete</button>
                            <button onClick={this.makeList.bind(this, {i})}>edit</button>
                        </td>
                    </tr>;
                })
            });
        }


        myDeleteItem(num) {

            this.props.deleteItem(num);

            this.setState({
                list: this.props.tasks.map((e, i) => {
                    const status = e.status ? 'green' : 'red';

                    return <tr key={i}>
                        <td onClick={this.myChangeStatus.bind(this,{i})} style={{color: status}}>{e.name}</td>
                        <td>
                            <button onClick={this.myDeleteItem.bind(this, {i})}>delete</button>
                            <button onClick={this.makeList.bind(this, {i})}>edit</button>
                        </td>
                    </tr>;
                })
            });


        }


        makeList(num = "undefined") {

            this.point = num.i;
            console.log(this.point);

            //формирую список задач
            //привязываю к клику метод родителя App, и передаю наверх (через .bind(null, param )) номер элемента массива, который нужно удалить
            this.setState({
                list: this.props.tasks.map((e, i) => {
                    const status = e.status ? 'green' : 'red';

                    return <tr key={i}>
                        {i == this.point ? <input /> : <td onClick={this.props.changeStatus.bind(null, {i})} style={{color: status}}>{e.name}</td>}
                        <td>
                            <button onClick={this.props.deleteItem.bind(null, {i})}>delete</button>
                            <button onClick={this.makeList.bind(this, {i})}>edit</button>
                        </td>
                    </tr>;
                })
            })

        }

        render() {

            return <table>
                <tbody>
                    {this.state.list}
                </tbody>
            </table>
        }
    }




    ReactDOM.render(
            <App/>,
        document.getElementById("content")
    )
  • Вопрос задан
  • 70 просмотров
Решения вопроса 1
rockon404
@rockon404 Куратор тега React
Frontend Developer
1. Почитайте про иммутабельность.
2. Никогда не изменяйте state напрямую.
3. По возможности не делайте bind в render.
4. Рефакторинг не имеет никакого отношения к перерисовке компонента.

createItem(task) {
  this.setState(prevState => ({
    tasks: [
      ...prevState.tasks,
      { name: task, status: false },
    ],
  }));
}


Весь остальной код по-хорошему бы переписать, но то, как это сделать выходит за рамки вашего вопроса.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
VGVolkov
@VGVolkov Автор вопроса
самоучка
пардон) я ошибся, имел ввиду рендеринг)
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы