1

I have TextField and FlatButton inside the Dialog. I want to save complete task list in an array which I defined in a state.

this.state = {
  open: false,
  todos: [{ id: -1, text: "", completed: false }],
  notetext: ""
};

I am able to get text of TextField from the state. I want to save task in an array on clicking of FlatButton. I have handleCreateNote function which is attached on tap on FlatButton.

I don't know what is the way to add task in an array. Can anyone help me what is the way in the react ?

const AppBarTest = () =>
  <AppBar
    title={strings.app_name}
    iconClassNameRight="muidocs-icon-navigation-expand-more"
    style={{ backgroundColor: colors.blue_color }}
  />;

class App extends Component {
  constructor(props) {
    injectTapEventPlugin();
    super(props);
    this.state = {
      open: false,
      todos: [{ id: -1, text: "", completed: false }],
      notetext: ""
    };
    this.handleChange = this.handleChange.bind(this);
  }

  handleOpen = () => {
    this.setState({ open: true });
  };

  handleClose = () => {
    this.setState({ open: false });
  };

  handleCreateNote = () => {
    console.log(this.state.notetext);
  };

  handleChange(event) {
    this.setState({ [event.target.name]: event.target.value });
  }

  render() {
    return (
      <MuiThemeProvider>
        <div>
          <AppBarTest />
          <FloatingActionButton
            style={styles.fab}
            backgroundColor={colors.blue_color}
            onTouchTap={this.handleOpen}
          >
            <ContentAdd />
          </FloatingActionButton>
          <Dialog
            open={this.state.open}
            onRequestClose={this.handleClose}
            title={strings.dialog_create_note_title}
          >
            <TextField
              name="notetext"
              hintText="Note"
              style={{ width: "48%", float: "left", height: 48 }}
              defaultValue={this.state.noteVal}
              onChange={this.handleChange}
            />

            <div
              style={{
                width: "4%",
                height: "48",
                backgroundColor: "red",
                float: "left",
                visibility: "hidden"
              }}
            />

            <FlatButton
              label={strings.create_note}
              style={{ width: "48%", height: 48, float: "left" }}
              onTouchTap={this.handleCreateNote}
            />
          </Dialog>

        </div>
      </MuiThemeProvider>
    );
  }
}

export default App;

2 Answers 2

7

First create a copy of existing state array, then use array.push to add a new data, then use setState to update the state array value.

Like this:

handleCreateNote = () => {
    let todos = [...this.state.todos];   //creating the copy

    //adding new data
    todos.push({
        id: /*unique id*/,
        text: this.state.notetext,
        completed: false
    });

    //updating the state value
    this.setState({todos});
};

Check this answer for details about "..." --> What do these three dots in React do?

MDN: Spread Operator

Update:

Instead of spread operator you can also use slice(), that will also return a new array, the key point is we need to create a copy of state array (before doing any change) by using any method.

Check this snippet:

let a = [{key: 1}, {key: 2}];

let b = [...a];

console.log('b', b);

Sign up to request clarification or add additional context in comments.

7 Comments

What . means here [...this.state.todos]; ?
It's the destructuring assignment. Read more here: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Actually it is spread syntax, which can be thought of as the opposite of destructuring assigment.
@ArneHugo Do you mean to convert props into an object ?
@Williams It can be used for multiple things. In this case, it's used to take every item in the array that this.state.todos points to, and add them to a new array. This way we avoid mutating the original array (like push does), to avoid confusion and reduce probability of bugs.
|
1

you can use concat to create a new array:

this.setState({
    todos: [].Concat(this.state.todos, {id, text,  complete})
})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.