2016-11-09 10 views
0

私はreact + reduxに新規です。私は、アクションをディスパッチするときに私のアプリが再レンダリングされないという問題に遭遇しました。しかし、私は状態を調べるためにgetState()を使用します。私は文書を検索しますが、問題の内容はまだ分かりません。ありがとう、ありがとう。Redux - ディスパッチ後にアプリが再レンダリングされない

コードが

==== actions.js ====

export const ADD_MAIL = 'ADD_MAIL'; 
export const DEL_MAIL = 'DEL_MAIL'; 

export function addMail(email) { 
    return { 
     type: ADD_MAIL, 
     email 
    } 
} 

export function delMail(id) { 
    return { 
     type: DEL_MAIL, 
     id 
    } 
} 

==== reducers.js ====以下の通りである

import { combineReducers } from 'redux' 
import { ADD_MAIL, DEL_MAIL } from '../actions/actions' 
import MAILS from '../data' 

function emails(state = MAILS, action) { 
    switch (action.type) { 
     case ADD_MAIL: 
      console.log("ADD_MAIL"); 

      return [ 
       action.email, 
       ...state 
      ]; 

     case DEL_MAIL: 
      let idx = state.length; 
      let i = 0; 

      // Find the target mail 
      while(idx--) { 
       if (state[idx] && state[idx].serialNo === action.id) 
        i = idx; 
      } 

      let arr1 = state.slice(0, i); 
      let arr2 = state.slice(i + 1); 

      let newList = arr1.concat(arr2); 

      console.log("DEL_MAIL"); 
      return newList; 

     default: 
      return state; 
    } 
} 

const rootReducer = combineReducers({ 
    emails 
}); 

export default rootReducer; 

= === main.js ====

import React from 'react' 
import { render } from 'react-dom' 
import { Router, Route, IndexRoute, browserHistory } from 'react-router' 
import { createStore } from 'redux' 
import { Provider } from 'react-redux' 
import { Menu } from './menu' 
import { Mail } from './main' 
import Inbox from './main' 
import rootReducer from './reducers/reducers' 

var store = createStore(rootReducer); 

class App extends React.Component { 
    constructor(props) { 
     super(props); 
    } 

    render() { 
     return (
      <div style={{height: '100%'}}> 
       <Menu /> 
       {this.props.children} 
      </div> 
     ); 
    } 
} 

class Home extends React.Component { 
    constructor(props) { 
     super(props); 
    } 

    render() { 
     return (
      <Inbox /> 
     ); 
    } 
} 

render(
    <Provider store={store}> 
     <Router history={browserHistory}> 
      <Route path="/" component={App}> 
       <IndexRoute component={Home} /> 
       <Route path="/inbox" component={Inbox} /> 
       <Route path="/message/:mailSerial" component={Mail} /> 
      </Route> 
     </Router> 
    </Provider>, 
document.getElementById('app-container')) 

答えて

0

はこれを試してみてください:

import React from 'react' 
import { render } from 'react-dom' 
import { Link } from 'react-router' 
import { connect } from 'react-redux' 
import { addMail, delMail } from './actions/actions' 
import * as btn from './module/button' 
import * as module from './module/module' 

class Inbox extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = { 
     searchText: '' 
    } 
    this.handleUserInput = this.handleUserInput.bind(this); 
    this.deleteMail = this.deleteMail.bind(this); 
    this.sendMail = this.sendMail.bind(this); 
    } 

    handleUserInput(searchText) { 
    this.setState({ 
     searchText: searchText 
    }); 
    } 

    deleteMail(obj) { 
    this.props.delMail(obj.serialNo); //Call the delMail action 
    console.log(store.getState()); 
    } 

    sendMail(newMail) { 
    this.props.addMail(newMail); //Call the addMail action 
    console.log(store.getState()); 
    } 

    render() { 
    let mails = []; 
    let search = this.state.searchText.toUpperCase(); 

    let emails = this.props.emails; 
    emails.map(mail => { 
     if (mail.from.toUpperCase().indexOf(search) !== -1) 
     mails.push(mail); 
    }); 

    let sender = (mails.length === emails.length) ? "all" : this.state.searchText; 

    return (
     <div className="main"> 
     <div className="toolbar"> 
      <span>You have {mails.length} message from {sender}.</span> 
      <module.SearchInput searchText={this.state.searchText} onUserInput={this.handleUserInput} />  
      <div className="functions"> 
      <btn.AddButton /> 
      </div> 
     </div> 

     <div className="mailList"> 
      { 
      mails.map(mail => (
       <div className="item" key={mail.serialNo}> 
        <div className="info sender">From: {mail.from}</div> 
        <div className="info date">{mail.date}</div> 
        <div className="info subject">Subject: {mail.subject}</div> 
        <div className="functions"> 
         <btn.ReadButton serialNo={mail.serialNo} /> 
         <btn.DeleteButton serialNo={mail.serialNo} deleteMail={this.deleteMail} /> 
        </div> 
       </div> 
      )) 
      } 
     </div> 
      <module.NewMailInput sendMail={this.sendMail} /> 
     </div> 
     ); 
    } 
} 

function mapStateToProps(state) { 
    return { 
     emails: state.emails 
    }; 
} 

//Connect the component to re-render when state change and 
// makes the emails and actions to be available through this.props 
export default connect(mapStateToProps, {delMail, addMail})(Inbox); 



//To connect Mail component which I suppose that is in another file 
function mapStateToProps(state) { 
    return { emails: state.emails }; 
} 
export default connect(mapStateToProps, {})(Mail); 
+0

回答と説明をありがとうございます。 別のメールがある場合、どのように受信トレイのthis.props.emailsにアクセスできますか、別の質問がありますか?ありがとう。 – Ezek

+0

私は理解していない申し訳ありません@Ezekは、私が代わりに 'Inbox'の' Mail'にthis.props.emailsにアクセスする方法を意味しましたか? –

+0

説明がわかりません。私は両方のコンポーネントで同じ状態を共有する方法を意味します。たとえば、ではthis.props.emailsを使用してメールにアクセスできます。 では、どうすればthis.props.emailsを使ってメールの状態にアクセスできますか? – Ezek

0

あなたのmain.jsファイルでは、受信トレイコンポーネントが作成されています。これはReactコンポーネントですが、Reduxコンポーネントはありません。

受信トレイコンポーネントをエクスポートするときに、このような操作を行う必要があります。 main.jsに1つ、app.jsで1:

module.exports = connect((store)=> { 
    return {emails: store.emails} 
})(Inbox) 
+0

申し訳ありませんが、私はミスを犯しました。 main.jsのコードの一部が欠けていますそれを編集しました。 – Ezek

0

あなたが2倍の店舗を持っています。 main.jsに1を取り外し、小道具として渡されたものを使用することを派遣する呼び出しを更新します。

class Inbox extends React.Component { 
    ... 

    deleteMail(obj) { 
     this.props.dispatch(delMail(obj.serialNo)); 
    } 

    ... 
} 
関連する問題