I’m building a React Firebase blog and I want to pass {color} from the ViewPosts component (child) to the App component (parent).
App looks like this:
function App() {
const [backgroundColor, setBackgroundColor] = useState("");
return (
<div className="app" style={{ background: backgroundColor }}>
<Router>
<Routes>
<Route exact path="/" element={<Login />} />
<Route exact path="/register" element={<Register />} />
<Route exact path="/reset" element={<Reset />} />
<Route exact path="/dashboard" element={<Dashboard />} />
<Route exact path="/view-posts" element={<ViewPosts setBackgroundColor={setBackgroundColor} />} />
<Route exact path="/create-post" element={<CreatePost />} />
<Route exact path="/edit-post/:id" element={<EditPost />} />
<Route exact path="/profile/:id" element={<Profile />} />
</Routes>
</Router>
</div>
);
}
export default App;
I tried passing the state {setBackgroundColor} to to the ViewPosts component.
This is what ViewPosts looks like:
const ViewPosts = props => {
const [posts, setPosts] = useState([]);
const [user, loading, error] = useAuthState(auth);
const [searchInput, setSearchInput] = useState("");
const [filteredPosts, setFilteredPosts] = useState([]);
const [color, setColor] = useState("");
return (
<Container>
<div>
<div>
<h5>Search for a post by keyword</h5>
<input
id="search-bar"
type="text"
value={searchInput}
onChange={handleSearchChange}
/>
</div>
<input
id="search-bar"
type="text"
value={color}
onChange={(e) => setColor(e.target.value)}
/>
<button
className="view-post-button"
onClick={() => props.setBackgroundColor(color)}
>
Change background
</button>
{sortPosts(filteredPosts).map(post => (
<div
className="single-post"
id={post.id}
key={post.id}
>
<h2
className="post-title"
>
{post.data.title}
</h2>
<h5>{convertTimestamp(post.data.created)}</h5>
<div
className="post-body"
dangerouslySetInnerHTML={createMarkup(post.data.body)}>
</div>
<img
className="post-image"
src={`${post.data.image}`} />
<br></br><br></br>
<Link to={"/edit-post/" + post.id}>
<button
className="view-post-button"
>
Edit
</button>
</Link>
<button
className="view-post-button"
onClick={() => handleDuplicate(post.id)}
>
Duplicate
</button>
<button
className="view-post-button"
onClick={() => handleDelete(post.id)}
>
Delete
</button>
</div>
))}
</div>
</Container>
);
};
export default ViewPosts;
I deleted the functions from ViewPosts for the sake of brevity, as I’m only concerned about the following lines in ViewPosts:
<input
id="search-bar"
type="text"
value={color}
onChange={(e) => setColor(e.target.value)}
/>
<button
className="view-post-button"
onClick={() => props.setBackgroundColor(color)}
>
I keep getting the error: Uncaught TypeError: props.setBackgroundColor is not a function.
Can someone help me figure out how to pass {color} from ViewPosts to {setBackgroundColor} in App?
2
Answers
I didn’t get the
TypeError
. You are on the right track and can definitely pass the setter function directly or use a handler.I provided a couple working examples below by extending your sample code to create a minimal reproduction of the question. Hope that helps!
You can type a color in the input and hit
Change color
to see the result.Solution/Demo
Using a handler:
https://codesandbox.io/s/lift-up-state-example-fk78go
Passing setter function as prop:
https://codesandbox.io/s/lift-up-state-pass-setter-as-prop-6jnykp
Relevant Links/Resources
Lifting State Up
Everything seems to be correct.
I think ViewPosts might have been used somewhere else without passing setBackgroundColor, and with just adding question mark or if condition to check if exist, your problem will be solved.
or