Same function called in different buttons and both are giving different output in Reactjs, javascript?

Viewed 200

This is my code

const [datatable, setDatatable] = useState({
  columns: [
    {
      label: 'Title',
      field: 'title',
      width: 200,
      attributes: { ariacontrols: 'DataTable', 'aria-label': 'Name' },
    },
    { label: 'Language', field: 'language', width: 500 },
    { label: 'Description', field: 'description', width: 200 },
    { label: '', field: 'publish', sort: 'asc', width: 300 },
  ],
  rows: [{ _id: '', title: '', description: '', language: '', publish: '' }],
});

useEffect(() => {
  axios.get('/admin/challenges').then((response) => {
    data = response.data;
    data.map((item) => {
      item.publish = (
        <Button
          onClick={() => {
            viewPage(item._id);
          }}
          size="small"
          variant="outlined"
          color="primary"
        >
          view
        </Button>
      );
    });
    setDatatable({
      ...datatable,
      rows: data,
    });
  });
}, []);

// Event handler for button

const viewPage = () => {
  console.log(datatable);
};

And I created seperate button and passed the same function 'viewPage' as a handler.

return (
  <div>
    <button onClick={viewPage}>Hello</button>
    <div>
      //a datatable('state datable is passed as props') where each row has button and its event handler is 'viewPage'                  
      <MDBDataTableV5
        hover
        entriesOptions={[5, 20, 25]}
        entries={5}
        pagesAmount={4}
        data={datatable}
      />
    </div>
  </div>
);

But When I clicked the button both are showing different results, the button I declared in table is giving me only initial state as output, but the other button is giving correct updated state. So I am confused by its working. So what I am missing here and why???

2 Answers

That is because the event handler redefined when the render function called. So re-rendered elements have a new eventHandler function and un-rendered elements have an old event handler function. You can use the arrow function or the callback function.

<button onClick={() => {
  console.log(datatable)
}} >Hello</button>

It is probably due to adding the button in useEffect hook. The viewPage function uses datatable variable. You would probibly need to add viewPage to to dependencies of the useEffect. But this wouldt work because you would make the request multiple time. You can store the result you got from the useEffect hook api call into a state variable and map when returning jsx.

Related