我正在构建一个动态呈现来自json定义的反应组件的应用程序。某些组件需要使用数据上下文进行渲染。然后,这些组件需要获取外部数据。我之前有一个天真的解决方案,用DataComponent包装这些组件,在挂载期间触发请求然后设置状态。这种方法很有效。
componentWillMount = () =>
provider
.get()
.then(data => this.setState({data}))
现在,我尝试使用redux提出一个解决方案,这样所有数据模式都会有一个reducer,每个组件都不需要管理自己的数据(可能来自与其他组件相同的源)。存储已正确初始化,我可以看到每当调度一个动作时,存储状态都会正确更新(我使用redux devtools进行验证,没有状态发生变化)。但是,组件不会使用新数据进行更新。初始调用后不会重新调用render
函数。
这是与我提出的类似的代码:
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]
})
这是商店的代码
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
}
}
在应用程序内部,还有另一个redux存储来管理渲染器状态。
编辑1: 添加github repo来演示问题 https://github.com/clydeespeno/redux-custom-store
编辑2: react-redux版本是5.0.2,发现有一个与自定义商店订阅相关的错误,已经至少在5.0.6上修复了
答案 0 :(得分:0)
react-redux版本是5.0.2,发现有一个与自定义提供的商店订阅相关的错误,已经至少在5.0.6上修复了
将react-redux更新为5.0.6解决了这个问题。这里描述了错误https://github.com/reactjs/react-redux/pull/589