2017-05-25 110 views
0

我試圖讓我的終極版第一個應用程序,我已經做了一個版本的這一點沒有終極版,我知道終極版不一定需要這一點,但我想學習終極版。如何在Redux中更改商店時重新渲染組件?

我有有待辦事項的陣列商店,我的行動成功調度,並更新商店。

我的任務組件列表連接到存儲和數組作爲它自己的組件中呈現的每個項目。

初始加載,我的待辦事項清單顯示,從商店的初始狀態的待辦事項,但一旦我更新從狀態的新項目沒有得到呈現。相反,返回組件數組的map方法表示它'不能讀取未定義的屬性'map'。

如何解決這個問題?

乾杯。

import React from 'react'; 
 
import ReactDOM from 'react-dom'; 
 
import { createStore } from 'redux'; 
 
import { Provider } from 'react-redux'; 
 
import Container from './components/Container.js' 
 
import TaskReducer from './reducers/Task.js' 
 

 
require("./index.css"); 
 

 
const defaultState = { 
 
    items: [ 
 
    "task 1", 
 
    "task 2" 
 
    ] 
 
}; 
 

 
const store = createStore(TaskReducer, defaultState); 
 

 
// Allows access to store in console log 
 
window.store = store; 
 

 
ReactDOM.render((
 
    <Provider store={store}> 
 
    <Container /> 
 
    </Provider> 
 
), 
 
    document.getElementById('wrapper') 
 
);

import React from 'react'; 
 
import ReactDOM from 'react-dom'; 
 
import TaskList from './TaskList.js'; 
 
import { createStore, bindActionCreators } from 'redux'; 
 
import * as ActionCreators from '../actions/Task.js'; 
 
import Redux from 'redux'; 
 
import {connect} from 'react-redux' 
 

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

 
    render() { 
 
    // What does this do??? 
 
    const {dispatch} = this.props; 
 
    const deleteItem = bindActionCreators(ActionCreators.deleteTodoItem, dispatch); 
 
    const addItem = bindActionCreators(ActionCreators.addTodoItem, dispatch); 
 

 
    function _onSubmit(e) { 
 
     e.preventDefault(); 
 
     addItem(e.target.elements.task.value); 
 
     // Resets the form 
 
     e.target.reset(); 
 
    } 
 

 
    return (
 
     <div className=""> 
 
     <header className="header"> 
 
      <h1>To Do:</h1> 
 
     </header> 
 
      <form autoComplete="off" onSubmit={_onSubmit}> 
 
      <input name="task" placeholder="Task" autoComplete="off"></input> 
 
      </form> 
 
      <TaskList /> 
 
     </div> 
 
    ); 
 
    } 
 
} 
 

 
const mapStateToProps = state => (
 
\t { 
 
\t \t items: state.items 
 
\t } 
 
); 
 

 
export default connect(mapStateToProps)(Container);

import React from 'react'; 
 
import Task from './Task'; 
 
import { connect } from 'react-redux'; 
 

 
let TaskList = (props) => { 
 
    console.log('items', props.items); 
 
    var tasks = (props.items).map((item, key) => { return <Task data={item} key={key} listItemKey={key} /> }) 
 

 
    return(
 
    <ul className="task-list"> 
 
     {tasks} 
 
    </ul> 
 
); 
 
} 
 

 
const mapStateToProps = state => (
 
\t { 
 
\t \t items: state.items 
 
\t } 
 
); 
 

 
export default connect(mapStateToProps)(TaskList);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

import * as action from '../actions/Task.js' 
 

 
export default function toDoItems(state = [], action) { 
 
    switch(action.type) { 
 
    case 'DELETE_ITEM': 
 
     return [ 
 
     ...state, 
 
     ]; 
 

 
    case 'ADD_ITEM': 
 
     console.log('ADD ITEM'); 
 
     console.log('Submitted value = ', action.submittedValue) 
 
     return [ 
 
     ...state, 
 
     // Reducer gets action object item and appends to array 
 
     action.submittedValue 
 
     ] 
 

 
    default: 
 
     return state; 
 
    } 
 
}

---減速---

import * as action from '../actions/Task.js' 
 

 
export default function toDoItems(state = [], action) { 
 
    switch(action.type) { 
 
    case 'DELETE_ITEM': 
 
     return [ 
 
     ...state, 
 
     ]; 
 

 
    case 'ADD_ITEM': 
 
     console.log('ADD ITEM'); 
 
     console.log('Submitted value = ', action.submittedValue); 
 
     console.log('the state', state); 
 
     return [ 
 
     ...state, 
 
     // Reducer gets action object item and appends to array 
 
     action.submittedValue 
 
     ] 
 

 
    default: 
 
     return state; 
 
    } 
 
}

--- ---行動

export function addTodoItem(submittedValue) { 
 
    return { 
 
     type: 'ADD_ITEM', 
 
     // The action object returned has the submittedValue 
 
     submittedValue 
 
    } 
 
} 
 

 
export function deleteTodoItem() { 
 
    return { 
 
     type: 'DELETE_ITEM', 
 
    } 
 
}

回答

1

我已經編輯任務列表的組成部分。你沒有使用地圖功能正常

import React from 'react'; 
 
import Task from './Task'; 
 
import { connect } from 'react-redux'; 
 

 
let TaskList = (props) => { 
 
console.log('items', props.items); 
 
var tasks = undefined; 
 
if(props.items && props.items.length > 0){ 
 
    tasks = props.items.map((item, key) => { return <Task data={item} 
 
    key={key} listItemKey={key} /> }) 
 
} //edited code 
 

 
    return(
 
    <ul className="task-list"> 
 
     {tasks} 
 
    </ul> 
 
); 
 
} 
 

 
const mapStateToProps = state => (
 
\t { 
 
\t \t items: state.items 
 
\t } 
 
); 
 

 
export default connect(mapStateToProps)(TaskList);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

至於商店使用以下方法來配置存儲在您的主文件。 ...

import TaskReducer from './reducers/Task.js'; 
import * as redux from 'redux'; 
function configure(initialState = {}){ 
    const reducers = redux.combineReducers({ 
     tasks : TaskReducer 
    }); 

    let store = redux.createStore(reducers, initialState); 

    return store; 
}; 

const store = configure(); 
// Allows access to store in console log 
window.store = store; 

ReactDOM.render((
    <Provider store={store}> 
    <Container /> 
    </Provider> 
), 
    document.getElementById('wrapper') 
); 
+0

這可以防止錯誤和我的狀態更新,但它仍然不會呈現頁面上的任何內容。我開始認爲我錯過了對Redux非常重要的事情。看來,只要我更新狀態,而狀態正確更新,組件的道具變得不確定。 – tomhughes

+0

在渲染方法中,如果您執行「console.log(道具)」,會得到什麼? –

+0

Props使用items數組和派發方法返回一個對象。我懷疑這個問題可能與我的reducer有關,我現在將添加源代碼。 – tomhughes

相關問題