开发者问题收集

在ReactJ中使用道具从父母到子女的数据无法正常工作

2016-02-15
429

我正在尝试将数据从父组件发送到子组件。 我正在使用 RPC 获取数据,因此最初数据可能不存在,但是当数据不可用时,我会返回“正在加载”

获取数据后,数据显示在父组件中,但是子组件根本没有被调用。 这是父代码:

var ReactDOM = require('react-dom')
var React = require('react')
var RPC = require('../RPC')
var connect = require('react-redux').connect
var ContentData = require('./content_data')
var Content= React.createClass({
    getInitialState : function(){
        return {};
    },
    componentDidMount : function(){
        console.log("called");
        var that=this;
        RPC.execute("content","search_read_path",[[],["title","body"]],{},function(err,data) {
            this.setState({data:data});
        }.bind(this));
    },
    render: function() {
        console.log("render is called");
        var data = this.state.data
        if (!data) return <div>Loading</div>;
        console.log("data is ",data,data.length);
        return <div>
                {data.map(function){
                <ContentData info={data}/>
            </div>}.bind(this))}
    },    
});
module.exports=Content;

以下是子组件:

var ReactDOM = require('react-dom')
var React = require('react')
var RPC = require('../RPC')
var connect = require('react-redux').connect
var ContentData= React.createClass({
    render: function() {
        data = this.props.info;
        return <div className="col-md-10 col-sm-10">
            <div className="content">
                <div className="content_body">
                    <h1 className="text-uppercase"></h1><span>date and Time</span>
                    <hr/>
                    <p>
                    This is the body Section
                    </p>
                    <p id="paragraph_footer">This is the footer. Can have special texts. Will be displayed only of there is any documetns in footer.</p>
                    <hr/>
                    <div className="visitor_box">
                        <form><span className="label label-default">Leave a Reply </span>
                            <input className="form-control input-sm" type="email" placeholder="Place your email"/>
                            <div className="form-group">
                                <textarea className="form-control input-sm" rows="2" placeholder="Your Comment"></textarea>
                            </div>
                            <button className="btn btn-success btn-sm" type="button">Submit </button>
                        </form>
                        <div className="previous_replies">
                            <h5>Sijan replied:</h5>
                            <p className="bg-info">Paragraph</p>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    },    
});

module.exports = connect(ContentData);

这是来自控制台的错误

render is called
bundle.js:21440 called
bundle.js:21466 RPC content search_read_path [Array[0], Array[2]] Object {}
bundle.js:21486 RPC OK content search_read_path [Object, Object]
bundle.js:21447 render is called
bundle.js:21450 data is  [Object, Object] 2
bundle.js:2478 Warning: wrapWithConnect(...): No `render` method found on the returned component instance: you may have forgotten to define `render`, returned null/false from a stateless component, or tried to render an element whose type is a function that isn't a React component.warning @ bundle.js:2478ReactCompositeComponentMixin.mountComponent @ bundle.js:7540wrapper @ bundle.js:1712ReactReconciler.mountComponent @ bundle.js:5904ReactMultiChild.Mixin._mountChildByNameAtIndex @ bundle.js:14703ReactMultiChild.Mixin._updateChildren @ bundle.js:14607ReactMultiChild.Mixin.updateChildren @ bundle.js:14555ReactDOMComponent.Mixin._updateDOMChildren @ bundle.js:11925ReactDOMComponent.Mixin.updateComponent @ bundle.js:11754ReactDOMComponent.Mixin.receiveComponent @ bundle.js:11699ReactReconciler.receiveComponent @ bundle.js:5954ReactCompositeComponentMixin._updateRenderedComponent @ bundle.js:7936ReactCompositeComponentMixin._performComponentUpdate @ bundle.js:7918ReactCompositeComponentMixin.updateComponent @ bundle.js:7847wrapper @ bundle.js:1712ReactCompositeComponentMixin.performUpdateIfNecessary @ bundle.js:7795ReactReconciler.performUpdateIfNecessary @ bundle.js:5969runBatchedUpdates @ bundle.js:6551Mixin.perform @ bundle.js:7011Mixin.perform @ bundle.js:7011assign.perform @ bundle.js:6508flushBatchedUpdates @ bundle.js:6569wrapper @ bundle.js:1712Mixin.closeAll @ bundle.js:7077Mixin.perform @ bundle.js:7024ReactDefaultBatchingStrategy.batchedUpdates @ bundle.js:11044enqueueUpdate @ bundle.js:6598enqueueUpdate @ bundle.js:6183ReactUpdateQueue.enqueueSetState @ bundle.js:6349ReactComponent.setState @ bundle.js:16202(anonymous function) @ bundle.js:21443$.ajax.success @ bundle.js:21489j @ jquery.min.js:2k.fireWith @ jquery.min.js:2x @ jquery.min.js:5b @ jquery.min.js:5
bundle.js:2478 Warning: propTypes was defined as an instance property on wrapWithConnect. Use a static property to define propTypes instead.warning @ bundle.js:2478ReactCompositeComponentMixin.mountComponent @ bundle.js:7566wrapper @ bundle.js:1712ReactReconciler.mountComponent @ bundle.js:5904ReactMultiChild.Mixin._mountChildByNameAtIndex @ bundle.js:14703ReactMultiChild.Mixin._updateChildren @ bundle.js:14607ReactMultiChild.Mixin.updateChildren @ bundle.js:14555ReactDOMComponent.Mixin._updateDOMChildren @ bundle.js:11925ReactDOMComponent.Mixin.updateComponent @ bundle.js:11754ReactDOMComponent.Mixin.receiveComponent @ bundle.js:11699ReactReconciler.receiveComponent @ bundle.js:5954ReactCompositeComponentMixin._updateRenderedComponent @ bundle.js:7936ReactCompositeComponentMixin._performComponentUpdate @ bundle.js:7918ReactCompositeComponentMixin.updateComponent @ bundle.js:7847wrapper @ bundle.js:1712ReactCompositeComponentMixin.performUpdateIfNecessary @ bundle.js:7795ReactReconciler.performUpdateIfNecessary @ bundle.js:5969runBatchedUpdates @ bundle.js:6551Mixin.perform @ bundle.js:7011Mixin.perform @ bundle.js:7011assign.perform @ bundle.js:6508flushBatchedUpdates @ bundle.js:6569wrapper @ bundle.js:1712Mixin.closeAll @ bundle.js:7077Mixin.perform @ bundle.js:7024ReactDefaultBatchingStrategy.batchedUpdates @ bundle.js:11044enqueueUpdate @ bundle.js:6598enqueueUpdate @ bundle.js:6183ReactUpdateQueue.enqueueSetState @ bundle.js:6349ReactComponent.setState @ bundle.js:16202(anonymous function) @ bundle.js:21443$.ajax.success @ bundle.js:21489j @ jquery.min.js:2k.fireWith @ jquery.min.js:2x @ jquery.min.js:5b @ jquery.min.js:5
bundle.js:2478 Warning: contextTypes was defined as an instance property on wrapWithConnect. Use a static property to define contextTypes instead.warning @ bundle.js:2478ReactCompositeComponentMixin.mountComponent @ bundle.js:7567wrapper @ bundle.js:1712ReactReconciler.mountComponent @ bundle.js:5904ReactMultiChild.Mixin._mountChildByNameAtIndex @ bundle.js:14703ReactMultiChild.Mixin._updateChildren @ bundle.js:14607ReactMultiChild.Mixin.updateChildren @ bundle.js:14555ReactDOMComponent.Mixin._updateDOMChildren @ bundle.js:11925ReactDOMComponent.Mixin.updateComponent @ bundle.js:11754ReactDOMComponent.Mixin.receiveComponent @ bundle.js:11699ReactReconciler.receiveComponent @ bundle.js:5954ReactCompositeComponentMixin._updateRenderedComponent @ bundle.js:7936ReactCompositeComponentMixin._performComponentUpdate @ bundle.js:7918ReactCompositeComponentMixin.updateComponent @ bundle.js:7847wrapper @ bundle.js:1712ReactCompositeComponentMixin.performUpdateIfNecessary @ bundle.js:7795ReactReconciler.performUpdateIfNecessary @ bundle.js:5969runBatchedUpdates @ bundle.js:6551Mixin.perform @ bundle.js:7011Mixin.perform @ bundle.js:7011assign.perform @ bundle.js:6508flushBatchedUpdates @ bundle.js:6569wrapper @ bundle.js:1712Mixin.closeAll @ bundle.js:7077Mixin.perform @ bundle.js:7024ReactDefaultBatchingStrategy.batchedUpdates @ bundle.js:11044enqueueUpdate @ bundle.js:6598enqueueUpdate @ bundle.js:6183ReactUpdateQueue.enqueueSetState @ bundle.js:6349ReactComponent.setState @ bundle.js:16202(anonymous function) @ bundle.js:21443$.ajax.success @ bundle.js:21489j @ jquery.min.js:2k.fireWith @ jquery.min.js:2x @ jquery.min.js:5b @ jquery.min.js:5
bundle.js:7961 Uncaught TypeError: inst.render is not a function

如您所见,数据显示在 bundle.js:21450 中,数据为 [Object, Object] 2

但是子组件未被调用。

我不确定我做错了什么,任何建议都很好。

2个回答

div 标签发生了一些奇怪的事情

您正在关闭 map 回调中的 div 。很确定这甚至不会编译,所以这是问题的一部分。

 return <div>
   {data.map(function){
     <ContentData info={data}/>
     </div>}.bind(this))}
 },

如果有疑问,请将您的 JSX 包裹在括号中并标识您的组件,以确保它们匹配。

return (
  <div>
   {data.map(function) {
     <ContentData info={data}/>
   }.bind(this))}
  </div>
);

您的回调不接受任何参数

当您通过数组进行映射时,元素将作为第一个参数传递给回调函数。您的代码中缺少这一点。

return (
  <div>
   {data.map(function(dataItem) {
     <ContentData info={data}/>
   }.bind(this))}
  </div>
);

您传递了错误的 props

在您的 JSX 内部,您将 data 作为 info prop 传递。这应该是 dataItem

return (
  <div>
   {data.map(function(dataItem) {
     <ContentData info={dataItem}/>
   }.bind(this))}
  </div>
);

Map 回调返回 undefined

传递给 map 的回调必须返回一个值才有用。将此代码转换为对 React API 的常规调用以查看问题。

return (
  <div>
   {data.map(function(dataItem) {
     React.createElement(ContentData, { info: dataItem });
   }.bind(this))}
  </div>
);

您的代码中没有 return 语句。虽然 JSX 很神奇,但它不会为您推断这一点,归根结底,它只是一种简化某些方法调用的奇特方式。

在调用 createElement 之前添加 return 语句。

return (
  <div>
   {data.map(function(dataItem) {
     return React.createElement(ContentData, { info: dataItem });
   }.bind(this))}
  </div>
);

或者使用 JSX 和箭头函数(隐式返回)。

return (
  <div>
   {data.map(item => <ContentData info={item} />)}
  </div>
);
Dan Prince
2016-02-15

看起来您的父元素中的此语句有些不对劲:

 return
   <div>
     {data.map(function){
       <ContentData info={data}/>
       </div>}.bind(this))}

如果您希望数据数组中每个对象有 1 个子对象,那么它应该看起来像这样:

return
  <div>
    {data.map(function(dataItem)          // Provide dataItem as parameter to function
      {
        <ContentData info={dataItem} />   // Render 1 ContentData child per data item
      })
    }
  </div>
wintvelt
2016-02-15