2016-04-11 16 views
1

Я пытаюсь интегрировать 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 event.

это выход я получаю на стороне сервера

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' } 

, как вы можете видеть, разъем посылает действие на каждое нажатии клавиши на входе. Нажатие на кнопку не вызывает к промежуточному либо

EDIT - я попытался преобразования компонент SIGNUP в качестве контейнера - но я до сих пор, кажется, та же проблема

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) 
+0

Можете ли вы воспроизвести эту проблему в CodePen или JSFiddle? –

+0

Выяснил, где я ошибся :) .. отправил мой ответ. Извините за то, что тратило ваше время – Kannaj

ответ

2

Оказывается, что проблема была на событие OnClick - я преобразовал событие OnClick в функцию, как показано ниже:

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

в отличие от

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

Yup, обработчики ВСЕГДА должны быть обратными вызовами, иначе они будут вызываться каждый раз, когда отображается рендеринг. И так как набрав вызывал функцию, которая claled 'this.setState', то компонент повторно отображается каждый раз, сразу же вызывая функцию' onClick' каждый раз! – ZekeDroid