2016-10-12 6 views
3

Redux(Reactと併用)で問題が発生しています。ここに私のコードは次のとおりです。React/Redux connectがstoreStateでMapStateToPropsを起動しない

/// <reference path="../../typings/index.d.ts"/> 

import "./polyfill.ts"; 

import * as React from 'react' 
import * as ReactDOM from 'react-dom' 
import { createStore, combineReducers } from 'redux' 
import { Provider, dispatch } from 'react-redux' 
import { Router, Route, browserHistory, IndexRedirect } from 'react-router' 
import { syncHistoryWithStore, routerReducer } from 'react-router-redux' 

import { Form, Input } from './components/form.tsx' 

import app from './reducers.ts' 

const store = createStore(
    combineReducers({ 
     app, 
     routing: routerReducer 
    }), 
    {}, 
    window.devToolsExtension && window.devToolsExtension() 
); 

import App from './views/app.tsx'; 
import Reminders from './views/reminders.tsx'; 
import Calendar from './views/calendar.tsx'; 
import Settings from './views/settings.tsx'; 
import Groups from './views/groups.tsx'; 
import Courses from './views/courses.tsx'; 
import Homework from './views/homework.tsx'; 

// Create an enhanced history that syncs navigation events with the store 
const history = syncHistoryWithStore(browserHistory, store); 

class Application extends React.Component<any,any> { 
    constructor(props){ 
     super(props); 
    } 
    render() { 
     var socket = io(); 
     socket.on('connect', function() { 
      setTimeout(function(){ 
       store.dispatch({ 
        type: "SOCKET_ESTABLISHED", 
        socket: socket 
       }); 
      }, 1000); 
     }); 
     socket.on('DATA', function(data){ 
      console.log("DATA"); 
      console.log(data); 
     }) 
     console.log(Groups); 
     return <Provider store={store}> 
      <Router history={history}> 
       <Route path="/" component={App}> 
        <IndexRedirect to="/reminders" /> 
        <Route path="reminders" component={Reminders}/> 
        <Route path="calendar" component={Calendar}/> 
        <Route path="settings" component={Settings}> 
         <Route path="groups" component={Groups}/> 
        </Route> 
        <Route path="homework" component={Homework} /> 
       </Route> 
      </Router> 
     </Provider> 
    } 
} 


ReactDOM.render(
    <Application/>, 
    document.getElementById('mount') 
); 

マイ減速ファイルは次のようになります

export default function app(state={ 
     connection: { 
      socket: null, 
      online: false 
     } 
    }, action: any) { 
     console.log(action); 
     switch(action.type){ 
      case "SOCKET_ESTABLISHED": 
       console.log(state.connection); 
       return Object.assign(state, { 
        connection: { 
         socket: action.socket, 
         online: true 
        } 
       }); 
      default: 
       return state; 
     } 
    }; 

そして、私のアプリケーションコンポーネントは以下の通りです:

import * as React from 'react'; 
import { connect } from 'react-redux'; 

import Top from '../components/top.tsx'; 
import Nav from '../components/nav.tsx'; 

class AppClass extends React.Component<any,any> { 
    constructor(props){ 
     super(props); 
    } 
    render() : JSX.Element { 
     return <div> 
      <Top/> 
      <Nav/> 
      {this.props.connection.online ? this.props.children : "Offline." } 
     </div> 
    } 
} 

var App = connect(function(state){ 
    return { 
     connection: state.app.connection 
    }; 
})(AppClass); 

export default App; 

だから、私は、私は明確にしましょう接続関数を使用してストアとAppPropsを同期させます。ページがロードされると、ソケット接続が作成され、store.connection.onlinetrueに変更するアクションSOCKET_ESTABLISHEDが発生します。すべて正常に動作します。Redux開発ツールは、ストアが正しく更新され、オンラインになっていることを示しています。 React開発ツールのConnect(AppClass)コンポーネントを見ると、そのstoreStateは最新ですが、AppClassの子コンポーネントに正しいプロップがなく、this.props.app.connection.onlineが真である場合はfalseです。私はそれが状態の突然変異から来るかもしれないが、Object.assignを使用して新しいストアが返されることを見ました(この関数はMDN Polyfillです)。

私は明確でありがとう!

(私はいくつかのインターフェース定義を無視されている場合がありますが、コンパイルするための活字体を使用していますことに注意してください)

答えて

1

return state 

を変更してみてください。状態を新しいオブジェクトにコピーし、新しいオブジェクトを変更する必要があります。

更新この:これに

return Object.assign(state, { 
    connection: { 
     socket: action.socket, 
     online: true 
    } 
}); 

return Object.assign({}, state, { 
    connection: { 
     socket: action.socket, 
     online: true 
    } 
}); 

// or this 
return { 
    ...state, 
    connection: { 
     socket: action.socket, 
     online: true 
    } 
} 

Reduxのは、減速から新しい状態を受信して​​、以前の状態と比較します。状態を直接変更すると、新しい状態と以前の状態はと同じオブジェクトになります。これは、これと似ています。

var state = { foo: 'bar' }; 
state.test = 'test'; 
var newState = state; 
// state === newState # true 

代わりに、あなたは実際に活字体が文句を言わないので、私は明示的なオブジェクトの命名で私の質問を更新しようと思って、正しく3ドット演算子をコンパイル

var state = { foo: 'bar' }; 
var newState = { ...state, test: 'test' }; 
// state === newState # false 
+1

ありがとう、魅力のように働いた! –

0

mapStateToProps機能は、コンポーネントのtrigerの再レンダリングに新しい状態オブジェクトを返す必要があります。

はあなたが減速機の内部の状態オブジェクトを変更している

return {...state} 
+0

を変更する前にオブジェクトをコピーします。とにかく、助けてくれてありがとう! –

関連する問題