Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 通过组件传输数据_Javascript_Reactjs_React Native_React Redux - Fatal编程技术网

Javascript 通过组件传输数据

Javascript 通过组件传输数据,javascript,reactjs,react-native,react-redux,Javascript,Reactjs,React Native,React Redux,我有父组件和子(listView)组件。我的目标是将后端调度的数据从父级发送到子级。我通过点击按钮来实现这一点。问题是,在第二个父按钮单击后,子按钮将渲染。也许我的错误在组件中的某个地方会收到道具 家长: class Parent extends Component { constructor(props) { super(props); this.state = { dataSource: '', noRe

我有父组件和子(listView)组件。我的目标是将后端调度的数据从父级发送到子级。我通过点击按钮来实现这一点。问题是,在第二个父按钮单击后,子按钮将渲染。也许我的错误在
组件中的某个地方会收到道具

家长:

class Parent extends Component {
    constructor(props) {
        super(props);
        this.state = {
            dataSource: '',
            noRepos: false
        };
    }

    componentWillReceiveProps(newProps) {
        this.setState({
            dataSource: newProps.data
        });
        this.validateData(newProps)
    }
    submitUsername() {
        if(this.validateInput()){
            this.props.dispatch({type: 'DUMMY', state: this.state.username});
        } else {
            this.setState({emptyInput: true});
        }
    }
    render() {
        return (
            ...
            <View>
                <ListViewComponent dataRecieved={this.state.dataSource} />
            </View>
            ...
        );
    }
}

export default connect(state => {
    return {
        data: state.data,
    };
})(Parent);
export default class ListViewComponent extends Component {
    constructor(props) {
        super(props);
        this.state = {
            dataSource: new ListView.DataSource({
                rowHasChanged: (r1, r2) => r1 !== r2,
            }),
        };
    }

    propTypes: {
        dataRecieved: PropTypes.func.string
    };

    componentWillReceiveProps(newProps) {
        this.setState({
            dataSource: this.state.dataSource.cloneWithRows(this.props.dataRecieved),
        });
    }
    renderRow(rowData) {
        return (
            <View>
                <Text>{rowData.name}</Text>
            </View>
        );
    }
    render() {
        return (
            <View>
                <ListView dataSource={this.state.dataSource}
                          enableEmptySections={true}
                          renderRow={this.renderRow} />
            </View>
        );
    }
}
类父级扩展组件{
建造师(道具){
超级(道具);
此.state={
数据源:“”,
诺雷波斯:错
};
}
组件将接收道具(新道具){
这是我的国家({
数据源:newProps.data
});
这个.validateData(newProps)
}
submitUsername(){
if(this.validateInput()){
this.props.dispatch({type:'DUMMY',state:this.state.username});
}否则{
this.setState({emptyInput:true});
}
}
render(){
返回(
...
...
);
}
}
导出默认连接(状态=>{
返回{
数据:state.data,
};
})(家长);
子项:

class Parent extends Component {
    constructor(props) {
        super(props);
        this.state = {
            dataSource: '',
            noRepos: false
        };
    }

    componentWillReceiveProps(newProps) {
        this.setState({
            dataSource: newProps.data
        });
        this.validateData(newProps)
    }
    submitUsername() {
        if(this.validateInput()){
            this.props.dispatch({type: 'DUMMY', state: this.state.username});
        } else {
            this.setState({emptyInput: true});
        }
    }
    render() {
        return (
            ...
            <View>
                <ListViewComponent dataRecieved={this.state.dataSource} />
            </View>
            ...
        );
    }
}

export default connect(state => {
    return {
        data: state.data,
    };
})(Parent);
export default class ListViewComponent extends Component {
    constructor(props) {
        super(props);
        this.state = {
            dataSource: new ListView.DataSource({
                rowHasChanged: (r1, r2) => r1 !== r2,
            }),
        };
    }

    propTypes: {
        dataRecieved: PropTypes.func.string
    };

    componentWillReceiveProps(newProps) {
        this.setState({
            dataSource: this.state.dataSource.cloneWithRows(this.props.dataRecieved),
        });
    }
    renderRow(rowData) {
        return (
            <View>
                <Text>{rowData.name}</Text>
            </View>
        );
    }
    render() {
        return (
            <View>
                <ListView dataSource={this.state.dataSource}
                          enableEmptySections={true}
                          renderRow={this.renderRow} />
            </View>
        );
    }
}
导出默认类ListViewComponent扩展组件{
建造师(道具){
超级(道具);
此.state={
数据源:新建ListView.dataSource({
行已更改:(r1,r2)=>r1!==r2,
}),
};
}
道具类型:{
接收的数据:PropTypes.func.string
};
组件将接收道具(新道具){
这是我的国家({
dataSource:this.state.dataSource.cloneWithRows(this.props.datareceived),
});
}
renderRow(行数据){
返回(
{rowData.name}
);
}
render(){
返回(
);
}
}

好的,一般的建议是始终保持单一的真相来源:

  • 不要将道具中已有的数据复制到内部组件状态。使用道具中的数据

  • 尽量创建无状态的组件(见上文…使用道具,或让组件监听“存储”。见Redux或AltJs)


特别是为了解决您的问题:

在父替换中:

  <ListViewComponent dataRecieved={this.state.dataSource} />
但要做到:

render() {

    var ds = new ListView.DataSource({
                    rowHasChanged: (r1, r2) => r1 !== r2,
    })
    , dataSource = ds.cloneWithRows(this.props.dataRecieved);

    return (
        <View>
                <ListView dataSource={dataSource}
            enableEmptySections={true}
            renderRow={this.renderRow} />
        </View>
    );
}
render(){
var ds=new ListView.DataSource({
行已更改:(r1,r2)=>r1!==r2,
})
,dataSource=ds.cloneWithRows(this.props.datareceived);
返回(
);
}

以上是未经测试的代码,但应作为遵循方法的指南。

您最初实现的
ListViewComponent
很好,在刷新
ListView
时,您应该使用
componentWillReceiveProps
。每个最佳实践都说要这样做(只需谷歌
react native redux listview
)。您只是在实现中有一个我在上面的评论中提到的小错误。另外,您不应该在
呈现
函数中重新创建
列表视图.DataSource
,这对性能不好,并且违背了
列表视图.DataSource中
行已更改
的目的

我所说的错误是:

componentWillReceiveProps(newProps) {
  this.setState({
    dataSource: this.state.dataSource.cloneWithRows(this.props.dataRecieved),
  });
}
应该是:

// ListViewComponent
componentWillReceiveProps(newProps) {
  this.setState({
    dataSource: this.state.dataSource.cloneWithRows(newProps.dataRecieved),
  });
}
另外,您的
父级
不应在其
状态下持有
数据源
,只需直接将
数据
传递到
列表视图组件
,因为Redux已经将其作为
道具
传递:

class Parent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      // ...
    };
  }

  componentWillReceiveProps(newProps) {
    // ...
  }

  submitUsername() {
    if (this.validateInput()) {
      this.props.dispatch({ type: 'DUMMY', ... });
    } else {
      // ...
    }
  }
  render() {
    return (
      ...
      <View>
        {/* this.props.data automatically comes from the `connect` wrapper below */}
        <ListViewComponent dataRecieved={this.props.data} />
      </View>
      ...
    );
  }
}

export default connect(state => {
  return {
    data: state.data,
  };
})(Parent);
类父级扩展组件{
建造师(道具){
超级(道具);
此.state={
// ...
};
}
组件将接收道具(新道具){
// ...
}
submitUsername(){
if(this.validateInput()){
this.props.dispatch({type:'DUMMY',…});
}否则{
// ...
}
}
render(){
返回(
...
{/*this.props.data自动来自下面的“connect”包装器*/}
...
);
}
}
导出默认连接(状态=>{
返回{
数据:state.data,
};
})(家长);

你也应该看看这个。这是一个如何在
列表视图
旁边使用Redux的示例。他的示例使用了
cloneWithRows和sections
,但因为没有sections,所以只能使用
cloneWithRows
进行调整。这个要点是由一位相当活跃的core React本地开发人员编写的。

1。在哪里可以看到数据副本?2.举个例子。你看这不是答案。这是一些指导原则,我认为数据复制的地方很明显。例如,在
Parent
this.setState({dataSource:newProps.data})中,这是副本还是引用?它正在将props中的数据克隆到状态中。如何避免这种情况?错误在于
ListViewComponent
组件将接收props
使用
this.props.dataReceived
,而不是
newProps.dataReceived
。另外,请检查您的拼写,它应该是
收到的
,而不是
收到的