【问题标题】:Redux actions get triggered unnecessarily on state changeRedux 操作在状态更改时被不必要地触发
【发布时间】:2016-04-11 21:32:58
【问题描述】:

我正在尝试将 socketCluster 与一个简单的 redux 应用程序集成。目前,只有一个特性可以获取组件当前状态的值,并通过中间件将其发送到服务器。

这是我的 actions.js 文件

export function signupRequest(creds){
  return{
    type: SIGNUP_REQUEST,
    isFetching: true,
    isAuthenticated: false,
    creds
  }
}

我的减速机:

function signUp(state={
  isFetching:false,
  isAuthenticated: localStorage.getItem('id_token')? true : false
},action)
{
  switch(action.type){
    case SIGNUP_REQUEST:
      return Object.assign({},state,{
        isFetching:true,
        isAuthenticated: false,
        user: action.creds
      })
}

我有一个中间件函数,负责将输入发送到服务器

middleware.js

export default socket => store => next => action => {
  socket.emit('action',action);
}

我的客户端 index.js 文件

const socket = connect();
const createStoreWithMiddleware = applyMiddleware(middlewares(socket))(createStore);
const store = createStoreWithMiddleware(reducer);

let rootElement = document.getElementById('root')

render(
  <Provider store={store}>
    <App/>
  </Provider>,rootElement
)

我的 App.jsx 容器:

class App extends Component{

  render(){
      const {dispatch,isAuthenticated,errorMessage,isFetching} = this.props;
    return(
      <Signup
        onButtonClick = {this.props.signupRequest}/>
    )
  }
}

function mapStateToProps(state){
  const {isAuthenticated,errorMessage,isFetching} = state.signUp

  return {
    isAuthenticated,
    errorMessage,
    isFetching
  }
}

function mapDispatchToProps(dispatch){
  return bindActionCreators({signupRequest:signupRequest},dispatch)
}

export default connect(mapStateToProps,mapDispatchToProps)(App);

我的注册组件:

class Signup extends Component{

  constructor(props){
    super(props);

    this.state = {name:''};
    this.onInputChange = this.onInputChange.bind(this)
  }

  onInputChange(event){
    this.setState({name:event.target.value})
  }

  render(){
    return (
      <div>
        <input type="text"
          ref="username"
          className="SignupUsername"
          placeholder="Username"
          value = {this.state.name}
          onChange={this.onInputChange}
          />
        <button onClick= {this.props.onButtonClick(this.state.name)} >
          Signup
        </button>
      </div>
    )
  }
}

export default Signup

我面临的问题是中间件/操作在输入中在每次按键时触发。我只想在按钮 Click 事件上调用中间件。

这是我在服务器端得到的输出

action recieved : { type: 'SIGNUP_REQUEST',
  isFetching: true,
  isAuthenticated: false,
  creds: 'a' }
action recieved : { type: 'SIGNUP_REQUEST',
  isFetching: true,
  isAuthenticated: false,
  creds: 'as' }
action recieved : { type: 'SIGNUP_REQUEST',
  isFetching: true,
  isAuthenticated: false,
  creds: 'asd' }
action recieved : { type: 'SIGNUP_REQUEST',
  isFetching: true,
  isAuthenticated: false,
  creds: 'asda' }
action recieved : { type: 'SIGNUP_REQUEST',
  isFetching: true,
  isAuthenticated: false,
  creds: 'asdas' }
action recieved : { type: 'SIGNUP_REQUEST',
  isFetching: true,
  isAuthenticated: false,
  creds: 'asdasd' }

如您所见,套接字在输入中的每次按键时都会发送操作。 点击按钮也不会调用中间件

编辑 - 我尝试将注册组件转换为容器 - 但我似乎仍然遇到同样的问题

class Signup extends Component{

  constructor(props){
    super(props);

    this.state = {name:''};
    this.onInputChange = this.onInputChange.bind(this)
  }

  onInputChange(event){
    this.setState({name:event.target.value})
  }

  render(){
    return (
      <div>
        <input type="text"
          ref="username"
          className="SignupUsername"
          placeholder="Username"
          value = {this.state.name}
          onChange={this.onInputChange}
          />
        <button onClick= {this.props.signupRequest(this.state.name)} >
          Signup
        </button>
      </div>
    )
  }
}

function mapDispatchToProps(dispatch){
  return bindActionCreators({signupRequest:signupRequest},dispatch)
}

export default connect(null,mapDispatchToProps)(Signup)

【问题讨论】:

  • 你能在 CodePen 或 JSFiddle 中重现这个问题吗?
  • 弄清楚我哪里出错了 :) .. 也发布了我的答案。很抱歉浪费您的时间

标签: javascript node.js reactjs redux socketcluster


【解决方案1】:

原来问题出在 onClick 事件上 - 我将 onClick 事件转换为如下函数:

<button onClick= {() => this.props.signupRequest(this.state.name)} >
  Signup
</button>

反对

  <button onClick= {this.props.signupRequest(this.state.name)} >
          Signup
        </button>

【讨论】:

  • 是的,处理程序总是必须是回调,否则每次视图呈现时都会调用它们。而且由于打字是调用一个名为this.setState的函数,所以每次点击时组件都会重新渲染,每次都立即调用onClick函数!
猜你喜欢
  • 2020-11-20
  • 2020-07-26
  • 2016-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-09
  • 2022-08-17
相关资源
最近更新 更多