I created a project where a component shows a list of Employees.
MyEmployee component:
import { useState } from "react";
export default function MyEmployee({
data = [],
page = 1,
size = 2,
total = 0
}) {
const [myEmployees, setMyEmployees] = useState(data);
const [currPage, setCurrPage] = useState(page);
const [rows, setRows] = useState(size);
const [totalData, setTotalData] = useState(total);
return (
<>
{console.log("data: ", data)}
{console.log("myEmployees: ", myEmployees)}
<h2>Some Employee</h2>
{myEmployees.map((emp) => {
console.log("iterate emp", emp);
return (
<div key={emp.id}>
<span>{emp.name}</span>
<span>{emp.email}</span>
</div>
);
})}
<button>{"<"}</button>
<span>
{currPage} of {Math.ceil(totalData / rows)}
</span>
<button>{">"}</button>
</>
);
}
then in App component I pass the props:
import { useEffect, useState } from "react";
import MyEmployee from "./MyEmployee";
import { getSomeData } from "./SomeService";
export default function App() {
const [employees, setEmployees] = useState({});
function getData() {
const emp = getSomeData();
console.log("emp: ", emp);
if (emp?.status) {
setEmployees(emp.data);
}
console.log("employees: ", employees);
}
useEffect(() => {
getData();
}, []);
return (
<div className="App">
{console.log("employees: ", employees)}
<MyEmployee
data={employees?.someEmployeeData?.obj}
page={employees?.someEmployeeData?.page}
size={employees?.someEmployeeData?.size}
total={employees?.someEmployeeData?.total}
/>
</div>
);
}
the props come from SomeService.js:
export function getSomeData() {
return {
status: true,
message: null,
data: {
someEmployeeData: {
page: 1,
size: 2,
total: 5,
obj: [
{
id: 1,
name: "Deas",
email: "[email protected]"
},
{
id: 2,
name: "Joey",
email: "[email protected]"
}
]
}
}
};
}
But i see that the props are not passed as the states in MyEmployee which initialized with the props have the deafult value. what did i miss / do wrong?
2
Answers
You are passing in the props but not setting the state inside the component, since you want them in different variables. Try adding
useEffect
inMyEmployee.js
When the component is initialized, every props that are loaded in are default value, so they are either
undefined
or the fallback value that you defined in the argument. These part specific.So when the states in
MyEmployee
is initialized, they are initialized the fallback value that you have defined ([]
,1
,2
, and3
). Since the only way to update the state is to usesetState
method, all of the state likemyEmployees
andcurrPage
are not being updated.The proper way is to not store them as state and read them directly, and get the updated values from the parent component that passes those values in as props.
Of course, the other alternative would be to use the
useEffect
to update those states withuseState
when the props are updated, but that will cause many unnecessary re-render as a caveat.