2017-08-25 17 views
1

json定義から反応コンポーネントを動的にレンダリングするアプリケーションを構築しています。一部のコンポーネントはデータコンテキストでレンダリングする必要があります。これらのコンポーネントは外部データを取得する必要があります。これらのコンポーネントをDataComponentでラップする前に、単純な解決策がありました。DataComponentは、マウント時に要求を起動し、状態を設定します。このアプローチは機能します。同じソースから来るかもしれないコンポーネントを手動でコンポーネントに渡すときにコンポーネントが再レンダリングされない(react-redux)

componentWillMount =() => 
    provider 
    .get() 
    .then(data => this.setState({data})) 

は今、私はすべてのデータスキーマが減速を持つことになりますように、Reduxのを使用して解決策を考え出すことを試み、そして各コンポーネントは、独自のデータを管理する必要はありません(他のコンポーネント)。ストアは適切に初期化されており、アクションがディスパッチされるたびにストア状態が正しく更新されていることがわかります(私はredux devtoolsを使用して検証していますが、状態は変更されていません)。ただし、コンポーネントは新しいデータで更新されません。 render関数は、最初の呼び出し後に再呼び出しされません。

は、ここに私が思い付いたものに類似したコードです:ここではアプリケーション内で店舗

import {createStore} from 'redux' 
import {combineReducers} from 'redux' 
import reduce from 'lodash/reduce' 
import has from 'lodash/has' 

export default (schemas) => createStore(
    createReducers(schemas), 
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() 
) 

const createReducers = (schemas) => combineReducers(reduce(schemas, accumulateReducers, {})) 

const accumulateReducers = (reducers, schema) => ({...reducers, [schema.id]: createReducer(schema)}) 

const createReducer = (schema) => { 
    return (state = getDefault(schema), {type, response}) => { 
     switch (type) { 
      case `${schema.id}_GET_SUCCESS`: 
       return {...state, [schema.id]: response} 
      default: 
       return state 
     } 
    } 
} 

const getDefault = (schema) => ({ 
    [schema.id]: getDefaultValue(schema) 
}) 

const getDefaultValue = (schema) => { 
    if (has(schema, 'defaultValue')) { 
     return schema.defaultValue 
    } 

    switch (schema.type) { 
     case 'array': 
      return [] 
     case 'object': 
      return {} 
     default: 
      return null 
    } 
} 

ためのコードです

import React from 'react' 
import {connect} from 'react-redux' 
import PropTypes from 'prop-types' 

// Component: React.Component 
// store: redux-store 
// schema: String 
export default function connectedComponent(Component, store, schema) { 

    class DataComponent extends React.Component { 

     static propTypes = { 
      // eslint-disable-next-line react/forbid-prop-types 
      data: PropTypes.any 
     } 

     static defaultProps = { 
      data: null 
     } 

     render =() => { 
      if (this.props.data) { 
       return this.renderComponent(Component, this.props.data) 
      } 
      return (<span>empty</span>) 
     } 

    } 

    renderComponent = (Component, data) => ... 

    // eslint-disable-next-line react/no-multi-comp,react/display-name 
    return (props) => { 
     const ConnectedData = connect(mapStateToProps(schema))(DataComponent) 
     return (
      <ConnectedData {...props} 
          store={store}/>) 
    } 
} 

const mapStateToProps = (schema) => (state) => ({ 
    data: state[schema][schema] 
}) 

、また、レンダラの状態を管理するための別のReduxの店があります。

編集1: が問題にデモするためにgithubのレポを追加 https://github.com/clydeespeno/redux-custom-store

編集2: 反応-Reduxのバージョンは、5.0.2であったカスタム用意ストアに対してサブスクリプションに関連するバグ、があったことが判明すでに固定少なくとも5.0.6

答えて

0

に反応する-Reduxのバージョンは5.0.2でした、すでに少なくとも5.0.6

更新に固定したカスタム提供店、に対してサブスクリプションに関連するバグがあったことが判明5.0.6に反応還元する問題を修正しました。バグはここに記載されていますhttps://github.com/reactjs/react-redux/pull/589

関連する問題