前提・実現したいこと
いつもお世話になってます。この度ReactにReduxを導入すべき基本的なReduxによるstate更新と再レンダリングまで行いたいと思い、まずは最低限Reduxを導入 → Redux経由でstate変更 → DOMに反映
まで行いたいです。
サンプルとして、↓スクショの「LIKE!」 をクリックすると、その下の文言が変わるコードを書いています。
発生している問題・エラーメッセージ
Redux経由でstate変更まではできているが、DOMに反映されない
該当のソースコード
Container
1import { connect } from 'react-redux'; 2import * as actions from '../actions/Index'; 3import Index from '../components/Index'; 4 5const mapStateToProps = state => { 6 return { 7 user: state.user, 8 emojies: state.emojies, 9 liked: state.liked, 10 } 11} 12 13const mapDispatchToProps = dispatch => { 14 return { 15 getEmojies: () => dispatch(actions.getEmojies()), 16 addLike: () => dispatch(actions.addLike()), 17 } 18} 19 20export default connect(mapStateToProps, mapDispatchToProps)(Index)
component
1import React, { Component, PropTypes } from 'react'; 2 3export default class Index extends Component { 4 constructor(props) { 5 super(props); 6 } 7 8 componentDidMount = (props) => { 9 this.props.getEmojies 10 } 11 12 render() { 13 // StoreのTodoからリストを生成 14 // const list = this.props.emojies.map((emoijes, index) => <li key={index}>{source}</li>) 15 console.log(this.props.state) // ←ここでstate更新できていることは確認できる 16 let liked = this.props.state ? 'LIKED!' : 'NO LIKED > <'; 17 return ( 18 <ul className="panel panel-default"> 19 <p onClick={this.props.addLike}>LIKE!</p> 20 {liked} 21 </ul> 22 ); 23 } 24}
actions
1const GET_USER = 'GET_USER' 2const GET_EMOJIES = 'GET_EMOJIES' 3const ADD_LIKE = 'ADD_LIKE' 4 5export const getEmojies = () => { 6 return { 7 type: GET_EMOJIES, 8 }; 9} 10 11export const addLike = () => { 12 return { 13 type: ADD_LIKE 14 }; 15}
reducenr
1import Api from '../helpers/api' 2 3const initialState = { 4 user: [], 5 emoji: [], 6 liked: false 7} 8 9export const indexReducer = (state = initialState, action) => { 10 switch (action.type) { 11 case 'GET_EMOJIES': 12 // 新しく追加するTODO 13 // stateを複製して追加 14 let emojies = { 0: { 'name': 'name' }, 1: { 'name': 'bbbbbbb' } } 15 const newEmojies = Object.assign({}, state, emojies) 16 17 return newEmojies 18 case 'ADD_LIKE': 19 const newLike = Object.assign({}, state, { liked: true }) 20 console.log(newLike); 21 return newLike 22 default: 23 return state 24 } 25}
createStore
1import { createStore as reduxCreateStore, applyMiddleware, combineReducers } from "redux"; 2import logger from "redux-logger"; 3import { indexReducer } from "./reducers/Index"; 4import createSagaMiddleware from 'redux-saga'; 5 6export default function createStore() { 7 const sagaMiddleware = createSagaMiddleware() 8 const store = reduxCreateStore( 9 combineReducers({ 10 state: indexReducer, 11 }), 12 applyMiddleware( 13 logger, 14 sagaMiddleware 15 ) 16 ) 17 18 return store; 19}
Root
1import React, { Component } from 'react'; 2import ReactDOM from 'react-dom'; 3 4import Index from './containers/Index' 5 6import { Provider } from 'react-redux'; 7import createStore from './createStore'; 8 9const store = createStore(); 10 11export default class Root extends Component { 12 render() { 13 return ( 14 <div className="container"> 15 <Index /> 16 </div> 17 ); 18 } 19} 20 21if (document.getElementById('root')) { 22 ReactDOM.render( 23 <Provider store={store}> 24 <Root /> 25 </Provider>, 26 document.getElementById('root')); 27} 28
といったコードで群でstateの更新をしており、componentでstateの更新を確認できています。
試したこと
Reducerでのshallow equal対策として、returnするオブジェクトは新規に作成しなおす
case 'ADD_LIKE': const newLike = Object.assign({}, state, { liked: true })
↓の質問にあるpropToStateの修正
https://teratail.com/questions/61126
全く原因がわからず困っておりますので、何かお気付きの方はご教授いただけますと幸いです。
よろしくお願いいたします。
補足情報(FW/ツールのバージョンなど)
packagejson
1 "devDependencies": { 2 "@babel/plugin-proposal-class-properties": "^7.5.5", 3 "@babel/preset-react": "^7.0.0", 4 "axios": "^0.19.0", 5 "cross-env": "^5.1", 6 "laravel-mix": "^4.0.7", 7 "lodash": "^4.17.13", 8 "react": "^16.2.0", 9 "react-dom": "^16.2.0", 10 "resolve-url-loader": "^2.3.1", 11 "sass": "^1.15.2", 12 "sass-loader": "^7.1.0" 13 }, 14 "dependencies": { 15 "react-redux": "^7.1.1", 16 "redux": "^4.0.4", 17 "redux-logger": "^3.0.6", 18 "redux-saga": "^1.0.5" 19 }
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。