我想在某些事件上显示快速闪光动画(例如,每次不正确的击键都会出现红色边框闪光)。
要使用css动画执行此操作,我需要在每次要触发闪存时删除并添加动画类。 (除非有另一种重新触发动画的方法吗?)。
在这个github线程上有一些建议:https://github.com/facebook/react/issues/7142
但是,在我的情况下,触发闪存的状态是redux状态。在许多情况下,国家实际上并没有改变,所以它不会导致重新报复。
这是我得到的最佳解决方案,包括设置随机数以强制重新渲染。有一个更好的方法吗?
reducer.js
//Reducer function to update redux state
function setError(state, action) {
state.hasError = true;
state.random = Math.random();
return state;
}
export default function allReducers(state = initialState, action) {
switch (action.type) {
case ActionTypes.SUBMIT_VALUE_BUTTON:
return Object.assign({}, state, setError(state, action));
default:
return state;
}
}
对组件和容器做出反应
const mapStateToProps = (state, ownProps) => {
return {
random: state.random,
hasError: state.hasError,
}
}
componentWillReceiveProps() {
this.setState({hasError: this.props.hasError});
setTimeout(() => {
this.setState({hasError: false});
}, 300)
}
render() {
return <div className = {`my-component ${this.state.hasError ? 'has-error':''}`} />;
}
编辑:值得注意的是,redux文档说你不应该在reducer方法中调用像Math.random这样的非纯函数。
你应该在减速机内做的事情:
调用非纯函数,例如Date.now()或Math.random()。
答案 0 :(得分:2)
你的代码中有一些问题,我会一个接一个地去......
您无法在reducer上改变状态对象。这是来自redux docs:
请注意:
我们不会改变国家。我们使用Object.assign()创建一个副本。 Object.assign(state,{visibilityFilter:action.filter})也是 错误:它会改变第一个参数。你必须提供一个空的 object作为第一个参数。您还可以启用对象传播 运营商建议改为编写{... state,... newState}。
在您的代码setError
中,将状态作为道具接收并进行变异。 setError
应如下所示:
function setError(state, action) {
let newState = Object.assign({}, state);
newState.hasError = true;
newState.random = Math.random();
return newState;
}
第二个问题可能是因为缺少一些代码,但是我无法确定你的状态何时恢复到没有错误,所以道具并没有真正改变。
在componentWillReceiveProps
引用this.props
而不是nextProps
。
componentWillReceiveProps
应如下所示:
componentWillReceiveProps(nextProps) {
if (nextProps.hasError !== this.props.hasError && nextProps.hasError){
setTimeout(() => {
// Dispatch redux action to clear errors
}, 300)
}
}
在你的组件中,你应该检查道具而不是说道,因为获取道具应该引起重新渲染(除非渲染在componentShouldUpdate
中停止):
render() {
return <div className={`my-component ${this.props.hasError ? 'has-error':''}`} />;
}