Home > Software design >  in reactJs onChangeHandler method is not working properly
in reactJs onChangeHandler method is not working properly

Time:01-25

I am trying to make a TO DO list app using Reactjs. onChangeTitleHandler is not setting the state of title when I type the title and the same happen with the onChangeTaskHandler. the new state is not setting up.

This is the Cockpit component.

const cockpit = (props) => {
    return (
        <div>
            <form onSubmit={props.submitted}>
                <input type="text" placeholder="Title" onChange={props.ChangeTitle} />
                <textarea rows={2} onChange={props.changeTask} />
                <input type='submit' value='ADD TASK'/>
            </form>
        </div>
    );
}

This is the code that I've tried.

this is my App.js file

import "./App.css";
import { React, Component } from "react";
import Cockpit from "./Components/Cockpit";

class App extends Component {

  state = {
    title:'',
    task: '',
    allTask : [] 
  };

  onChangeTitleHandler = (event)=>{
    this.setState={
      title: event.target.value,
    }
    console.log(this.state.title);
  }
  
  onChangeTaskHandler =(event)=>{
    this.setState={
      task: event.target.value,
    }
    console.log(this.state.title);
  }

  onSubmitHandler =(event) => {
    const tasks = this.state.allTask;
    tasks.push({
      title:this.state.title,
      task:this.state.task
    })

    this.setState={
      allTask:tasks
    }
    console.log(tasks);
    event.preventDefault();
  };

  render() {
    return (
      <div className="App">
        <h1 className="heading">Prioritise Your Tasks</h1>
        <Cockpit 
        ChangeTitle = {this.onChangeTitleHandler}
        changeTask={this.onChangeTaskHandler}
        submitted = {this.onSubmitHandler}
        />
      </div>
    );
  }
}

export default App;

I want that onSubmit the new state of title and task added in to the allTask array.

CodePudding user response:

There is a lot going on confusingly or wrongly in your example.

The main thing is that pointed out by Nils: that you are assigning a value to the setState function rather than using it as intended (calling it).

So instead of

  onChangeTaskHandler =(event)=>{
    this.setState={
      task: event.target.value,
    }
    console.log(this.state.title);
  }

you need to do

  onChangeTaskHandler = event => {
    this.setState({ task: event.target.value })
  }

Which leads me to one other thing that may be confusing your "output", which is that your are logging this.state.title immediately after calling the this.setState function. This won't have your expected outcome as the setState function is asynchronous, and therefore may not be as fast as you need it to for it to show the updated state in the console.log call.

As a latter point, from my personal point of view, your code style is somewhat confusing in the way you are naming things. Calling "submitted" to the onSubmit function handler sounds more of a boolean than of a function. Having properties starting with uppercase letters like ChangeTitle may be commonly interpreted as that being a react node or a class of some sort.

Also, for your example, a good idea would be to split the state of the task container, from that of the task itself. Having the container state being just the array, and each task item handling it's own state (title and description). This would give I think greater clarity to what you're trying to achieve.

But, conventions and clarity aside, I'd recommend that you follow the React hands-on tutorial to go through a whole bunch of concepts and good practices that may be of help and will save you a lot of time of try and error (at least this works for me)

CodePudding user response:

You problem lies in you trying to set state by adding an object to the setstate function this.setState={task: event.target.value}. setState is a function that you need to send your new state as a parameter for example setState({task: event.target.value}). This will set the state to {task: event.target.value}.

I have created a snippet that should work, here the issues with your code should be fixed.

Also you need to reference your functional component with case sensivity, meaning it should be Cockpit with a capital C.

const Cockpit = (props) => {
  return (
    <div>
      <form onSubmit={props.submitted}>
        <input type="text" placeholder="Title" onChange={props.ChangeTitle} />
        <textarea rows={2} onChange={props.changeTask} />
        <input type="submit" value="ADD TASK" />
      </form>
    </div>
  );
};

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      title: "",
      task: "",
      allTask: []
    };
  }

  onChangeTitleHandler = (event) => {
    this.setState({
      title: event.target.value
    });
  };

  onChangeTaskHandler = (event) => {
    this.setState({
      task: event.target.value
    });
  };

  onSubmitHandler = (event) => {
    const tasks = this.state.allTask;
    tasks.push({
      title: this.state.title,
      task: this.state.task
    });

    this.setState({
      allTask: tasks
    });
    console.log(tasks);
    event.preventDefault();
  };

  render() {
    return (
      <div className="App">
        <h1 className="heading">Prioritise Your Tasks</h1>
        <Cockpit
          ChangeTitle={this.onChangeTitleHandler}
          changeTask={this.onChangeTaskHandler}
          submitted={this.onSubmitHandler}
        />
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("container"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="container"></div>

  • Related