我已经开始使用react-redux并发现它是一种非常有趣的方法来简化应用程序的前端代码,使用从后端服务获取的许多对象,其中对象需要更新前端几乎是实时的。
使用容器类可以在很大程度上自动化观察(在更改时更新商店中的对象)。这是一个例子:
const MethodListContainer = React.createClass({
render(){
return <MethodList {...this.props} />},
componentDidMount(){
this.fetchAndWatch('/list/method')},
componentWillUnmount(){
if (isFunction(this._unwatch)) this._unwatch()},
fetchAndWatch(oId){
this.props.fetchObject(oId).then((obj) => {
this._unwatch = this.props.watchObject(oId);
return obj})}});
在尝试为应用程序的其余部分提供尽可能简单明了的分离时,我试图提供一种替代方案来连接&#39;因此会自动提供合适的容器:
const connect = (mapStateToProps, watchObjectId) => (component) => {
const ContainerComponent = React.createClass({
render(){
return <component {...this.props} />
},
componentDidMount(){
this.fetchAndWatch()},
componentWillUnmount(){
if (isFunction(this._unwatch)) this._unwatch()},
fetchAndWatch(){
this.props.fetchObject(watchObjectId).then((obj) => {
this._unwatch = this.props.watchObject(watchObjectId);
return obj})}
});
return reduxConnect(mapStateToProps, actions)(ContainerComponent)
};
然后使用它:
module.exports = connect(mapStateToProps,&#39; / list / method&#39;)(MethodList)
但是,component
无法呈现。除了component
未实例化或呈现之外,呈现容器。如果我不将其作为参数传递并直接引用它,component
会按预期呈现(和更新)。
不会产生任何错误或警告。
我做错了什么?
答案 0 :(得分:0)
尝试为component
参数使用不同的变量名称。
const connect = (mapStateToProps, watchObjectId) => (MyComponent) => {
const ContainerComponent = React.createClass({
render() {
return <MyComponent {...this.props} obj={this.state.obj} />
}
...
fetchAndWatch() {
fetchObject(watchObjectId).then(obj => {
this._unwatch = watchObject(watchObjectId);
this.setState({obj});
})
}
});
...
}
我认为问题可能是因为组件是小写的(<component {...this.props} />
)。 JSX将小写元素视为DOM元素,并将其大写为React元素。
编辑:
如果您需要访问obj
数据,则必须将其作为道具传递给组件。更新了代码段
答案 1 :(得分:0)
这是我的解决方法,而不是对错误的解释:
在connect_obj.js中:
ProgrammingError: (_mysql_exceptions.ProgrammingError) (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM `Genes`' at line 2") [SQL: u'SELECT \nFROM `Genes`']
然后我可以在任何地方使用它:
"use strict";
import React from 'react';
import {connect} from 'react-redux';
import {actions} from 'redux/main';
import {gets} from 'redux/main';
import {isFunction, omit} from 'lodash';
/*
A connected wrapper that expects an oId property for an object it can get in the store.
It fetches the object and places it on the 'obj' property for its children (this prop will start as null
because the fetch is async). It also ensures that the object is watched while the children are mounted.
*/
const mapStateToProps = (state, ownProps) => ({obj: gets.getObject(state, ownProps.oId)});
function connectObj(Wrapped){
const HOC = React.createClass({
render(){
return <Wrapped {...this.props} />
},
componentDidMount(){
this.fetchAndWatch()},
componentWillUnmount(){
if (isFunction(this._unwatch)) this._unwatch()},
fetchAndWatch(){
const {fetchObject, watchObject, oId} = this.props;
fetchObject(oId).then((obj) => {
this._unwatch = watchObject(oId);
return obj})}});
return connect(mapStateToProps, actions)(HOC)}
export default connectObj;
所以"use strict";
import React from 'react';
import connectObj from 'redux/connect_obj';
const Method = connectObj(React.createClass({
render(){
const {obj, oId} = this.props;
return (obj) ? <p>{obj.id}: {obj.name}/{obj.function}</p> : <p>Fetching {oId}</p>}}));
实现了我的目标,即创建一个项目范围的替代品,用于显式设置连接以及用于观察/取消监视对象的容器组件。这节省了相当多的锅炉板,并为我们提供了一个单独的位置来维护商店到组件的设置和连接,这些组件的工作只是呈现可能随时间变化的对象(通过服务更新)。
我仍然不明白为什么我的第一次尝试不起作用,这种解决方法不支持注入其他状态道具(因为所有操作都可用,所以不需要担心调度)。