Reputation: 185
I am making a small app to learn Redux. Here I would like to pass the props (id, title, todos) to AllItemTodo from ItemList, which I get from AllItemList.js, but I don't know how to do it.
Here are my codes for this matter: AllItemList.js
import { useSelector } from "react-redux";
import ItemList from "./ItemList";
import NewListButton from "./NewListButton";
const AllItemList = () => {
const lists = useSelector((state) => state.entities.lists);
return (
<div className="all-item-list">
<NewListButton />
{lists.map((item) => (
<ItemList
id={item.listInfo.id}
key={item.listInfo.id}
title={item.listInfo.title}
todos={item.todos}
/>
))}
</div>
);
};
export default AllItemList;
ItemList.js
import React from "react";
import { useDispatch } from "react-redux";
import { listRemoved } from "../store/rlists";
const ItemList = ({ id, title, todos }) => {
const dispatch = useDispatch();
const listRemoving = () => {
dispatch(listRemoved({ id }));
};
return (
<div>
<button className="list-remove" onClick={listRemoving}>
remove list
</button>
</div>
);
};
export default ItemList;
AllItemTodo.js
import NewTodoButton from "./NewTodoButton";
import Nav from "./Nav";
const AllItemTodo = ({ id, title, todos }) => {
return (
<div className="all-item-todo">
<Nav />
<NewTodoButton />
</div>
);
};
export default AllItemTodo;
App.js
import AllItemList from "./components/AllItemList";
import AllItemTodo from "./components/AllItemTodo";
import { useSelector } from "react-redux";
function App() {
return (
<div className="App">
<AllItemList />
<AllItemTodo />
</div>
);
}
export default App;
Please help! I really appreciate it.
Upvotes: 1
Views: 108
Reputation: 185
So I found an answer by using useState() and put it in the parent file App.js, then pass it down to both children. But I don't know if this is a good practice or not since we are using Redux at the moment. Please let me know your opinions:
App.js
import AllItemList from "./components/AllItemList";
import AllItemTodo from "./components/AllItemTodo";
import { useSelector } from "react-redux";
import { useState } from "react";
function App() {
const lists = useSelector((state) => state.entities.lists);
const [currentList, setCurrentList] = useState(lists[0]);
return (
<div className="App">
<AllItemList currentList={currentList} setCurrentList={setCurrentList} />
<AllItemTodo currentList={currentList} setCurrentList={setCurrentList} />
</div>
);
}
export default App;
All
import { useSelector } from "react-redux";
import ItemList from "./ItemList";
import NewListButton from "./NewListButton";
const AllItemList = ({ setCurrentList, currentList }) => {
const lists = useSelector((state) => state.entities.lists);
return (
<div className="all-item-list">
<NewListButton />
{lists.map((item) => (
<ItemList
currentList={currentList}
setCurrentList={setCurrentList}
id={item.listInfo.id}
key={item.listInfo.id}
title={item.listInfo.title}
todos={item.todos}
/>
))}
</div>
);
};
export default AllItemList;
ItemList.js
const ItemList = ({
hello,
setCurrentList,
currentList,
list,
id,
title,
todos,
}) => {
const dispatch = useDispatch();
const listRemoving = () => {
dispatch(listRemoved({ id }));
};
const clickOnCurrentList = () => {
setCurrentList(list);
console.log(currentList);
};
return (
<div>
<button className="current-list" onClick={clickOnCurrentList}>
select list
</button>
</div>
);
};
export default ItemList;
AllItemTodo.js
import NewTodoButton from "./NewTodoButton";
import Nav from "./Nav";
const AllItemTodo = ({ currentList, setCurrentList }) => {
return (
<div className="all-item-todo">
<h2>{currentList}</h2>
<Nav />
<NewTodoButton />
</div>
);
};
export default AllItemTodo;
Upvotes: 0
Reputation: 4613
So you have to pass the props from the child to its parent (ItemList
-> App
) and then pass it down from parent to child (App
-> AllItemTodo
).
Passing props from parent to child (the ordinary way) you already know. It is theoretically the only way (the intended way) to pass props. The trick here is to "pass props up" and you can acheive it simply by passing a callback function down. Then in the child, which is receiving this function as a prop, you can call this function with the values you want to "pass up" as its arguments, i.e.:
Parent.js
const Parent = () > {
const getPropsFromChild = (values) => {
console.log('values in parent: '+values);
}
return (
<Child passPropsToParent={ (values) => getPropsFromChild(values) } />
);
}
Child.js
const Child = (props) => {
const values = [1, 2, 3];
useEffect(() => {
console.log('values in child: '+values);
props.passPropsToParent(values);
}, []);
}
Upvotes: 3