【发布时间】:2019-12-03 21:16:40
【问题描述】:
我有一个小问题 在我更新数组中一个元素的状态后,我需要渲染所有元素,即使是那些没有改变其状态的元素。
我有 Waiter 组件,其中带有状态按钮,我正在更新一张桌子的状态。
class Waiter extends React.Component {
static propTypes = {
fetchTables: PropTypes.func,
loading: PropTypes.shape({
active: PropTypes.bool,
error: PropTypes.oneOf(PropTypes.bool,PropTypes.string),
}),
tables: PropTypes.any,
postTableStatus: PropTypes.func,
}
componentDidMount(){
const { fetchTables } = this.props;
fetchTables();
}
onClick(e, tableId, status, order) {
e.preventDefault();
if(status === 'free'){
status = 'thinking';
}
else if(status === 'thinking'){
status = 'ordered';
}
else if(status === 'ordered'){
status = 'prepared';
}
else if(status === 'prepared'){
status = 'delivered';
}
else if(status === 'delivered'){
status = 'paid';
}
else if(status === 'paid'){
status = 'free';
}
this.props.postTableStatus(tableId, status, order);
}
renderActions(status, id, order){
switch (status) {
case 'free':
return (
<>
<Button onClick={(e) => this.onClick(e, id, status, order)}>thinking</Button>
<Button onClick={(e) => this.onClick(e, id, status, order)}>new order</Button>
</>
);
case 'thinking':
return (
<Button onClick={(e) => this.onClick(e, id, status, order)}>new order</Button>
);
case 'ordered':
return (
<Button onClick={(e) => this.onClick(e, id, status, order )}>prepared</Button>
);
case 'prepared':
return (
<Button onClick={(e) => this.onClick(e, id, status, order)}>delivered</Button>
);
case 'delivered':
return (
<Button onClick={(e) => this.onClick(e, id, status, order)}>paid</Button>
);
case 'paid':
return (
<Button onClick={(e) => this.onClick(e, id, status, order)}>free</Button>
);
default:
return null;
}
}
render() {
const { loading: { active, error }, tables } = this.props;
console.log('props',this.props);
if(active || !tables.length){
return (
<Paper className={styles.component}>
<p>Loading...</p>
</Paper>
);
} else if(error) {
return (
<Paper className={styles.component}>
<p>Error! Details:</p>
<pre>{error}</pre>
</Paper>
);
} else {
return (
<Paper className={styles.component}>
<Table>
<TableHead>
<TableRow>
<TableCell>Table</TableCell>
<TableCell>Status</TableCell>
<TableCell>Order</TableCell>
<TableCell>Action</TableCell>
</TableRow>
</TableHead>
<TableBody>
{tables.map(row => (
<TableRow key={row.id}>
<TableCell component="th" scope="row">
{row.id}
</TableCell>
<TableCell>
{row.status}
</TableCell>
<TableCell>
{row.order && (
<Button to={`${process.env.PUBLIC_URL}/waiter/order/${row.order}`}>
{row.order}
</Button>
)}
</TableCell>
<TableCell>
{this.renderActions(row.status, row.id, row.order)}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Paper>
);
}
}
}
当 Waiter 组件正在加载时,一切都呈现良好。但是在我更新一张桌子后全部卡在
Loading...
这是我的 WaiterContainer.js
const mapStateToProps = state => ({
tables: getAll(state),
loading: getLoadingState(state),
});
const mapDispatchToProps = dispatch => ({
fetchTables: () => dispatch(fetchFromAPI()),
postTableStatus: (table, status, order) => dispatch(putToTableStatus(table, status, order)),
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(Waiter);
和tablesRedux.js 文件
/* selectors */
export const getAll = ({ tables }) => tables.data;
export const getLoadingState = ({ tables }) => tables.loading;
export const postOrderStatus = ({ tables }) => tables.status;
/* action name creator */
const reducerName = 'tables';
const createActionName = name => `app/${reducerName}/${name}`;
/* action types */
const FETCH_START = createActionName('FETCH_START');
const FETCH_SUCCESS = createActionName('FETCH_SUCCESS');
const FETCH_ERROR = createActionName('FETCH_ERROR');
const POST_STATUS = createActionName('POST_STATUS');
/* action creators */
export const fetchStarted = payload => ({ payload, type: FETCH_START });
export const fetchSuccess = payload => ({ payload, type: FETCH_SUCCESS });
export const fetchError = payload => ({ payload, type: FETCH_ERROR });
export const postStatus = payload => ({ payload, type: POST_STATUS });
/* thunk creators */
export const fetchFromAPI = () => {
return (dispatch, getState) => {
dispatch(fetchStarted());
Axios.get(`${api.url}/${api.tables}`)
.then(res => {
dispatch(fetchSuccess(res.data));
})
.catch(err => {
dispatch(fetchError(err.message || true));
});
};
};
// tableId, newStatus, newOrder
export const putToTableStatus = (tableId, newStatus, newOrder) => {
return (dispatch, getState) => {
Axios.patch(`${api.url}/${api.tables}/${tableId}`, {status: newStatus, order: newOrder})
.then(res => {
console.count('table spread',tableId);
console.count(' status',newStatus);
console.count(' order',newOrder);
dispatch(postStatus(res.data));
console.log('data', res.data);
console.log('postStatus1',postStatus(res.data));
});
};
};
/* reducer */
export default function reducer(statePart = [], action = {}) {
switch (action.type) {
case FETCH_START: {
return {
...statePart,
loading: {
active: true,
error: false,
},
};
}
case FETCH_SUCCESS: {
return {
...statePart,
loading: {
active: false,
error: false,
},
data: action.payload,
};
}
case POST_STATUS: {
return{
...statePart,
data: action.payload,
};
}
default:
return statePart;
}
}
我更新前的道具是 6 个表的数组
tables: Array(6)
0: {id: 1, status: "thinking", order: null}
1: {id: 2, status: "thinking", order: null}
2: {id: 3, status: "free", order: 1234}
3: {id: 4, status: "free", order: 3647}
4: {id: 5, status: "free", order: 12340}
5: {id: 6, status: "free", order: 45207}
length: 6
但更新后我得到的只是我刚刚更新的表
tables:
id: 4
order: 3647
status: "thinking"
不知道如何让它工作:/ 这是最新的提交Link
【问题讨论】:
标签: javascript reactjs redux