Redux动作在状态改变时被不必要地触发
我正在尝试将socketCluster与一个简单的redux应用程序集成在一起。 目前,只有一个function可以将组件当前状态的值通过中间件发送给服务器。
这是我的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 }) }
我有一个中间件function,负责发送到服务器的input
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
我面临的问题是中间件/操作在input中的每个按键都被触发。 我只想在buttonClick事件上调用中间件。
这是我在服务器端得到的输出
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' }
正如你所看到的,套接字是在input中的每个按键发送动作。 点击button也不会调用中间件
编辑 – 我试图转换注册组件作为一个容器 – 但我似乎仍然有同样的问题
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)
原来问题出在onClick事件 – 我把onClick事件转换成如下函数:
<button onClick= {() => this.props.signupRequest(this.state.name)} > Signup </button>
正如所反对的那样
<button onClick= {this.props.signupRequest(this.state.name)} > Signup </button>