Reputation: 452
I've got this functional component. I want to call a dispatcher when .delete is clicked. I've made an example of what I expected to do onClick:
import React from 'react'
import { Link } from 'react-router-dom'
export default function FeedItem(article) {
return (
<div className="feed-item flex-column" key={article.id}>
<Link to={`/posts/${article.id}`} className="title">{article.title}</Link>
<div className="delete" onClick={() => dispatch({someType})}>X</div>
<p>{article.body}</p>
<Link to={`/edit`} params={{postid: article.id}} className="edit">edit</Link>
</div>
)
}
How should it been done right?
Upvotes: 7
Views: 7279
Reputation: 1113
You can use HOC or from React 16.8.0 you can also use Hook
HOC
An higher-order component is a function that takes a component and returns a new component with more "features"
Example:
const EnhancedComponent = higherOrderComponent(WrappedComponent);
HOC
React Hooks are functions that let us hook into the React state and lifecycle features from function components.
Example
function Example() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0); // useState is an hook
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
HOW?
ANSWER Using HOC
import { connect } from 'react-redux';
function FeedItem({ article, onClick }) {
return (
<div className="feed-item flex-column" key={article.id}>
<Link to={`/posts/${article.id}`} className="title">{article.title}</Link>
<div className="delete" onClick={(e) => onClick(e)}>X</div>
<p>{article.body}</p>
<Link to={`/edit`} params={{postid: article.id}} className="edit">edit</Link>
</div>
)
}
const mapDispatchToProps = dispatch => {
return {
// explicitly forwarding arguments
onClick: event => dispatch({ type: 'SOME_TYPE', payload: event }),
}
}
export default connect(null, mapDispatchToProps)(FeedItem)
ANSWER Using HOOK
import { useDispatch } from 'react-redux';
export default function FeedItem(article) {
const dispatch = useDispatch();
return (
<div className="feed-item flex-column" key={article.id}>
<Link to={`/posts/${article.id}`} className="title">{article.title}</Link>
<div className="delete" onClick={() => dispatch({ someType })}>X</div>
<p>{article.body}</p>
<Link to={`/edit`} params={{ postid: article.id }} className="edit">edit</Link>
</div>
);
}
DOCS:
Upvotes: 1
Reputation: 11760
You can use useDispatch
hook which gives you a reference to the dispatch
function
import { useDispatch } from 'react-redux';
export default function FeedItem(article) {
const dispatch = useDispatch();
return (
<div className="feed-item flex-column" key={article.id}>
<Link to={`/posts/${article.id}`} className="title">{article.title}</Link>
<div className="delete" onClick={() => dispatch({ someType })}>X</div>
<p>{article.body}</p>
<Link to={`/edit`} params={{ postid: article.id }} className="edit">edit</Link>
</div>
);
}
Upvotes: 11
Reputation: 14159
you have to connect your component: https://react-redux.js.org/using-react-redux/connect-mapdispatch#defining-mapdispatchtoprops-as-an-object
import React from 'react'
import { Link } from 'react-router-dom'
import { connect } from 'react-router'
function FeedItem(props) {
return (
<div className="feed-item flex-column" key={props.id}>
<Link to={`/posts/${props.id}`} className="title">{article.title}</Link>
<div className="delete" onClick={props.dispatchSomething}>X</div>
<p>{article.body}</p>
<Link to={`/edit`} params={{postid: article.id}} className="edit">edit</Link>
</div>
)
}
const dispatchSomething = data => ({ payload: data, type: 'foo' })
export default connect(null, { dispatchSomething })(FeedItem);
Upvotes: 0
Reputation: 2938
Hi Max,
connect
your component to have an acess to dispatch
from redux-thunk
.connect
will provide the dispatch
, and will take an object fo dispatchers, which in this case would be an onClick
action.import React from 'react';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
function FeedItem({ article, onClick }) {
return (
<div className="feed-item flex-column" key={article.id}>
<Link to={`/posts/${article.id}`} className="title">{article.title}</Link>
<div className="delete" onClick={(e) => onClick(e)}>X</div>
<p>{article.body}</p>
<Link to={`/edit`} params={{postid: article.id}} className="edit">edit</Link>
</div>
)
}
const mapDispatchToProps = dispatch => {
return {
// explicitly forwarding arguments
onClick: event => dispatch({ type: 'SOME_TYPE', payload: event }),
}
}
export default connect(null, mapDispatchToProps)(FeedItem)
Upvotes: 1