我对redux还是很陌生,但仍在努力使自己湿透。我正在开发一个微型应用程序,该应用程序从端点获取数据并呈现项目。然后,用户可以“固定”这些项目,这是我不确定的部分。
在我的操作中,我已经设置了获取数据的逻辑
import {FETCH_POST} from './types';
export function fetchPost() {
console.log('fetch..');
return function (dispatch) {
fetch('https://someapi/.json?count=20')
.then(res => res.json())
.then(posts =>
dispatch({
type: FETCH_POST,
payload: posts.data.children
})
)
;
}
}
我的减速器有条件处理此动作
import {FETCH_POST} from '../actions/types';
const initialState = {
items: [],
item: {}
};
export default function(state = initialState, action){
switch (action.type){
case FETCH_POST:
return Object.assign({}, state, {items: action.payload});
default:
return state;
}
}
//Main reducer file
import {combineReducers} from 'redux';
import postReducer from './postReducer';
export default combineReducers({
post: postReducer
});
这是我的组成部分
class Post extends Component{
componentWillMount(){
this.props.fetchPost();
}
pinPost(){
//...not sure how to update here
}
render(){
const postItems = this.props.posts.map(post => (
<div key={post.data.id} className="listBox">
<div className="listContent">
<i className="fa fa-thumb-tack pin" onClick={this.pinPost}></i>
<a href={'https://someapi' + post.data.permalink} target="_blank">{post.data.title}</a>
</div>
</div>
));
return(
<div>
<h1>Pinned</h1>
<hr/>
<h1>Posts</h1>
{postItems}
</div>
);
}
}
我在这里的目标是能够通过单击图标来固定帖子,然后在“固定”部分而不是“帖子”部分下显示该帖子。
this.props.posts
数组由对象组成,这些对象默认具有pinned: false
的属性以及与其绑定的其他属性。我希望将其设置为“ true”(如果固定),并重置为“ false”(如果固定)。
我将如何处理?我需要采取其他措施来解决这个问题吗?
答案 0 :(得分:1)
想法是,首先您需要在redux存储区的onClick固定按钮中更新特定帖子的固定属性。为此,您需要将唯一属性(帖子ID)与onClick方法绑定在一起,并使用该ID调度一个动作。
步骤:
1-将每个帖子的唯一ID传递给pinPost方法:
onClick={this.pinPost.bind(this, post.data.id)}
2-发送操作以更新Redux存储中该帖子的pinned
属性:
pinPost(id) {
this.props.updatePost(id)
}
3-将updatePost定义为:
updatePost(id) {
dispatch({
type: 'UPDATE_POST',
id,
})
}
4-现在,在reducer中更新该帖子的pinned
属性:
export default function(state = initialState, action){
switch (action.type){
case FETCH_POST:
return Object.assign({}, state, {items: action.payload});
case UPDATE_POST:
const items = state.items.map(el => el.data.id == action.id ?
{data: Object.assign({}, el.data, { pinned: true })} : el
return Object.assign({}, state, { items })
default:
return state;
}
}
5-现在在不同部分渲染元素:
render(){
let pinnedPost = [], postItems = []
this.props.posts.forEach(post => {
if(post.data.pinned) {
pinnedPost.push(
<div key={post.data.id} className="listBox">
<div className="listContent">
<i className="fa fa-thumb-tack pin"></i>
<a href={'https://someapi' + post.data.permalink} target="_blank">{post.data.title}</a>
</div>
</div>
)
} else {
postItems.push(
<div key={post.data.id} className="listBox">
<div className="listContent">
<i className="fa fa-thumb-tack pin" onClick={this.pinPost}></i>
<a href={'https://someapi' + post.data.permalink} target="_blank">{post.data.title}</a>
</div>
</div>
)
}
));
return(
<div>
<h1>Pinned</h1>
{pinnedPost}
<hr/>
<h1>Posts</h1>
{postItems}
</div>
);
}