Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't set props to state using useState React

I'm new to react. I've read through react documentation. I've no idea why it is not working. So, I come up here.

I'm trying to create pagination in react. Below is my table component.

const Table = (props) => {
  const { description, itemCount, tableHeaders, items } = props;

  const pageSize = 5;
  const [currentPage, setCurrentPage] = useState(1);

  function handlePageChange(page) {
    setCurrentPage(page);
  }

  const registerations = paginate(items, currentPage, pageSize);
  // HERE: registerations data is correct and then I pass it to TableBody component.

  return (
    <React.Fragment>
      <TableDescription description={description} count={itemCount} />
      <div className="bg-white block w-full md:table">
        <TableHeader items={tableHeaders} />
        <TableBody items={registerations} />
      </div>
      {/* Footer & Pagination */}
      <div className="bg-white block flex px-6 py-4 justify-between rounded-bl-lg rounded-br-lg">
        <div className="sm:flex-1 sm:flex sm:items-center sm:justify-between">
          <Pagination
            itemsCount={items.length}
            pageSize={pageSize}
            currentPage={currentPage}
            onPageChange={handlePageChange}
          />
        </div>
      </div>
      {/* end Footer & Pagination */}
    </React.Fragment>
  );

and that registerations array is received by TableBody component. The problem here in TableBody component is that I can't set props value to state using useState hook.

const { items: passedItems } = props;
console.log(passedItems); // ok -> I got what I passed.

const [items, setItems] = useState(passedItems);
console.log(items); // not ok -> items is previously passed items.

How can I make it right? Thank You.

like image 739
Htet Phyo Naing Avatar asked Jun 06 '20 15:06

Htet Phyo Naing


People also ask

Can I use props in useState?

Passing useState as props in another component is totally possible. But there's no benefit in doing so because you can always call useState by importing React at the top of your JavaScript code and call it in all of your components. This is a bad practice, and you should never use useState like this.

How do I change props to state in React?

Component { state = { description: '' } constructor (props) => { const { description } = props; this. state = {description}; } render () { const {state: { description }} = this; return ( <input type="text" value={description} /> ); } } export default SecondComponent; Update: I changed setState() to this.

How do you send states as props in React Hooks?

Passing props to state using useState Hooks import React, { useState } from 'react'; const Profile = props => { const [profileState, setProfileState] = useState(props); return ( <div> <p> <strong>Name:</strong> {profileState.name} </p> <p> <strong>Email:</strong> {profileState.


2 Answers

I you want this to work in it's current form:

const { items: passedItems } = props;
console.log(passedItems); // ok -> I got what I passed.

const [items, setItems] = useState([]);
console.log(items); // not ok -> items is previously passed items.
useEffect(() => {
  setItems(passedItems)
}, [passedItems])
like image 66
Łukasz Karczewski Avatar answered Sep 30 '22 05:09

Łukasz Karczewski


While use useState hooks you should understand why we need useEffect, so in class based components you had the privilege to use callback function in this.setState which will give you the current updated value

this.setState(() => {
  name: 'john'
}, () => console.log(this.state.name)) // you will get the immediate updated value

So when you come to functional component

const [name, setName] = useState(props.name)
console.log(name) // won't get the updated value

for to get the updated value you can use React.useEffect hook which will trigger whenever array deps as the second argument got changed.

useEffect(() => {
 // logic based on the new value
}, [name]) // so whenever the name value changes it will update and call this useEffect

the useEffect can be called in three ways

First One

Without passing an array of deps

useEffect(() => {}) // this will call everytime

Second One

Passing empty array

 useEffect(() => {}, []) // passing empty array,it will call one time like the componentDidMount of class based component

Third One

Passing array deps (dependencies)

 useEffect(() => {

} , [name, count]) // whenever there is an update of name and count value it will call this useEffect

So in your case you can do the below way

useEffect(() => {
  setItems(passedItems)
}, [passedItems]) // whenever passedItems changes this will call and setItems will set the new passedItems

I hope you have clear idea on this.

like image 45
Learner Avatar answered Sep 30 '22 05:09

Learner