使用react + redux添加/删除动画类

时间:2018-04-12 03:07:15

标签: javascript reactjs redux

我想在某些事件上显示快速闪光动画(例如,每次不正确的击键都会出现红色边框闪光)。

要使用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()。

1 个答案:

答案 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':''}`} />; 
}