Reputation: 1362
I'm trying to find a way to pass a state to an action or a reducer. For example
I want to be able to run the onDelete
function on the action then update the state on the reducer. However, in order for this to work, i would need to filter through the posts then i would able to remove a post.
class Posts extends Component {
state = {
posts: [],
loading: true,
}
getPosts = () => {
Axios.get(process.env.REACT_APP_GET_POSTS)
.then( (res) => {
this.setState({
posts: res.data,
loading: false
})
})
// console.log(this.state.posts);
}
componentWillMount(){
this.getPosts();
}
// run this logic on the reducer or on actions.
onDelete = (id) => {
Axios.post(`/api/posts/delete/${id}`);
this.setState({
posts: this.state.posts.filter(post => post.id !== id)
})
}
render() {
const {loading, posts} = this.state;
if (!this.props.isAuthenticated) {
return (<Redirect to='/signIn' />);
}
if(loading){
return "loading..."
}
return (
<div className="App" style={Styles.wrapper}>
<h1> Posts </h1>
<PostList DeletePost={this.onDelete} posts={posts}/>
</div>
);
}
}
Here is the attempt to make into an action, which technically works.
actions
export const DeletePost = (id) => {
return (dispatch) => {
return Axios.post(`/api/posts/delete/${id}`)
.then( () => {
dispatch({type: DELETE_POST, id});
});
}
}
Then we approach the problem of actually getting the posts on the reducer. The problem is that the reducer does not know where the posts are coming from, its undefined. So i want to know how would i pass the state to the reducer.
and will return
state.posts.filter is not a function or something along those lines.
reducer.js
import { DELETE_POST} from '../actions/';
const initialState = {
post: [],
postError: null,
posts:[]
}
export default (state = initialState, action) => {
switch (action.type) {
case DELETE_POST:
return ({
...state,
posts: state.posts.filter(post=> post.id !== action.id)
})
default:
return state
}
}
How would i get pass the state to the actions, so that i would be able to update the state on the reducer ?
Upvotes: 1
Views: 1202
Reputation: 319
I'm trying to find a way to pass a state to an action or a reduce
The way you wrote your actions code indicates you're using redux thunk, which means you can access the getState
function in your action. Example usage of getState is here
export const DeletePost = (id) => {
return (dispatch, getState) => {
return Axios.post(`/api/posts/delete/${id}`)
.then( () => {
dispatch({type: DELETE_POST, id});
});
}
}
you already have access to the state in your reducer code. Its called state
!
Now, the above could the end of the answer. But I'm questioning the premise of what you're doing in the class.
// run this logic on the reducer or on actions.
onDelete = (id) => {
Axios.post(`/api/posts/delete/${id}`);
this.setState({
posts: this.state.posts.filter(post => post.id !== id)
})
}
Above you're filtering for the posts after you've already filtered/deleted it from redux (i.e. you're filtering unnecessarily twice). You should instead just be getting the state directly from redux
Take a look here. For an example of this being used in a more robust setting. I would direct you to this example. For the example, look at src/containers/visibleTodoList
So really for what you're doing, posts
should just live with redux and not in the class component!
Lastly for the error you saw
state.posts.filter is not a function or something along those lines.
Could you give the exact error? your reducer code seems fine.
Upvotes: 2