Dan
Dan

Reputation: 623

Way to pass props and display in a list in react

I am encountering issues when trying to display the props in an ordered list. It only displays the initial value. When I add to the list, it was not updated.

Here is the source code

TodoList.js

class ToDoList extends React.Component {

    render() {
        return (
            <div>
                {this.props.data.map(list => {
                    return (
                        <ol key={list.uuid} > <input type="checkbox"></input>{list.uuid}- {list.text}</ol>
                    );
                })}
            </div>
        );
    }
}

export default ToDoList;

Todo.js
let data = [{ uuid: 100, text: "TEST" }, { uuid: 101, text: "TEST" }];
let id = 0;

class Todo extends React.Component {
    handleAddItem = () => {
        id = id + 1;
        data.push({ uuid: id, text: this.refs.textInput.value });
        console.log(data);
    }

    render() {
        return (
            <div>
                <div>
                    <input type="text" ref="textInput"></input>
                    <button onClick={this.handleAddItem}>ADD TO LIST</button>
                </div>
                <ToDoList data={data} />
            </div>
        );
    }
}

export default Todo;

Thank you.

Upvotes: 0

Views: 680

Answers (2)

Joseph D.
Joseph D.

Reputation: 12174

When I add to the list, it was not updated.

It's because data is not a state variable and does not cause a re-render.

To fix, make it a state instead.

class Todo extends React.Component {
  // make data and id a state variable
  state = {
    data: [{ uuid: 100, text: "TEST" }, { uuid: 101, text: "TEST" }],
    id: 0,
  }
  ...
}

Then pass state data to TodoList

<ToDoList data={this.state.data} />

WHEN UPDATING STATE:

Never mutate a state variable in your handler by using spread operator (...).

handleAddItem = () => {
  // update the state using this.setState()
  this.setState(prevState => ({
      id: prevState.id + 1,
      data: [
        ...prevState.data, // use spread operator
        { uuid: prevState.id + 1, text: this.refs.textInput.value }
      ]
    }),
    () => console.log(this.state.data) // pass 2nd arg to log state update
  );
}

Upvotes: 4

user11081925
user11081925

Reputation:

You should add state to ToDo component add use setSate() method to update state. Then the ToDo component and ToDoList component will re-render.

let data = [{ uuid: 100, text: "TEST" }, { uuid: 101, text: "TEST" }];
let id = 0;

class Todo extends React.Component {
    state = {
        data
    }

    handleAddItem = () => {
        id = id + 1;
        this.setSate({
            data: [...this.state.data, { uuid: id, text: this.refs.textInput.value }]
        });
        console.log(this.state.data);
    }

    render() {
        return (
            <div>
                <div>
                    <input type="text" ref="textInput"></input>
                    <button onClick={this.handleAddItem}>ADD TO LIST</button>
                </div>
                <ToDoList data={this.state.data} />
            </div>
        );
    }
}

There is the doucment about Component State. Read it to learn more.

Upvotes: 1

Related Questions