如何在子组件中调用父组件值

时间:2018-09-20 12:05:11

标签: firebase react-native firebase-realtime-database react-navigation

你好,我正在创建本机应用程序。在此应用程序主页中包含项目列表和过滤器按钮。当我单击过滤器按钮时,过滤器屏幕将打开,该屏幕包含3个过滤器下拉菜单。用户将从下拉列表中选择值,然后单击过滤器按钮。用户单击过滤器按钮页面后,应将其重定向到主页,并使用新的过滤器数据重新生成列表。现在,我想将过滤器值传递给主页的子组件,但是我没有得到如何将数据发送到主页的子组件的信息。我可以在控制台窗口中获取所有过滤器值,但是我不知道该如何将该值传递给组件上的新数据。

这是我的代码:

HomeScreen.js

      render() {
    return (
      <View style={styles.container}>
        <HomeProject />
        <View>
          <TouchableHighlight
            style={styles.addButton}
            underlayColor='#ff7043' onPress={() => NavigationService.navigate('Filters', { filterCallback: filterValue => this.onFilterCallback(filterValue) })}>
            <Text style={{ fontSize: 20, color: 'white' }}>+</Text>
          </TouchableHighlight>
        </View>
      </View>
    );
  }
   onFilterCallback(filterValue) {
        console.log('-> Callback value:', filterValue);
        this.setState({ filterValue: filterValue });
      }

HomeProject.js

class HomeProject extends Component {
  constructor(props) {
    super(props)
  }

  componentWillMount() {
   this.props.fetchProjectList();
    this.createDataSource(this.props);
  }

  componentWillReceiveProps(nextProps) {
    console.log('nextProps' + JSON.stringify(nextProps));
    console.log('receive' + JSON.stringify(nextProps.filterValue));
     this.createDataSource(nextProps);
  }

  createDataSource({ projectlist }) {
    console.log('111');
    console.log('projetclist' + projectlist);
    const ds = new ListView.DataSource({
      rowHasChanged: (r1, r2) => r1 !== r2
    });

    this.dataSource = ds.cloneWithRows(projectlist);
  }

  renderRow(data) {
    console.log('222');
    const { currentUser } = firebase.auth();
  //  if (data.userid !== currentUser.uid && !data.isDraft) {
        return (<ProjectList data={data} />);
  //  }

  }

  render() {
    return (
      <View style={{ flex: 1 }}>
          <ListView
            style={{ flex: 1 }}
            dataSource={this.dataSource}
            renderRow={this.renderRow}
          />
      </View>
    );
  }
}

FilterScreen.js

 onGoBack() {
    console.log('Filter is in going back');
    const { userprofile } = this.props;
    const { type } = userprofile;
      console.log('type :' + type);

        const ref = firebase.database().ref('projects');
        const query = ref.orderByChild('type').equalTo(type);
        query.on('value', (snapshot) => {
          console.log('project detail ', snapshot.val());

          const filterProjects = [];

          snapshot.forEach((item) => {
            filterProjects.push({ key: item.key, 
              userid: item.val().userid,
              title: item.val().title,
              location: item.val().location
            });
          });
          console.log("filterProjects: ", filterProjects);


        if (this.params && this.params.filterCallback) this.params.filterCallback(filterProjects);
        console.log('goback');
        this.props.navigation.goBack();

  }


    renderButton() {
    return (
      <Button
        style={{ alignItems: 'center' }}
        onPress={this.onGoBack.bind(this)}
      >
        Filter
      </Button>
    );
  }
 render() {
const { navigate } = this.props.navigation

  return (
      <ScrollView style={{ flex: 1, backgroundColor: '#ffffff' }}>
          {this.renderLoading()}

            <DropDown
                label="Project Type"
                containerStyle={{
                  width: 100,
                  //zIndex: 60,
                  top: 20,

                  }}
                onValueChange={(value) => this.props.userProfile({ prop: 'type', value })}
                selectedValue={this.props.userprofile.type}
              >
                {Object.keys(this.props.types).map((key) => {

                    return (<Picker.Item
                      label={this.props.types[key]}
                      value={this.props.types[key]}
                      key={key}
                    />);
                })}
            </DropDown>

            <DropDown
              label="Language"
              containerStyle={{
                width: 140,
                //zIndex: 60,
                top: 20,

                }}
              onValueChange={(value) => this.props.userProfile({ prop: 'category', value })}
              selectedValue={this.props.userprofile.category}
            >
              {Object.keys(this.props.categories).map((key) => {

                  return (<Picker.Item
                    label={this.props.categories[key]}
                    value={this.props.categories[key]}
                    key={key}
                  />);
              })}
            </DropDown>

            <DropDown
              label="Keywords"
              containerStyle={{
                width: 140,
                //zIndex: 60,
                top: 20,

                }}
              onValueChange={(value) => this.props.userProfile({ prop: 'category', value })}
              selectedValue={this.props.userprofile.category}
            >
              {Object.keys(this.props.categories).map((key) => {

                  return (<Picker.Item
                    label={this.props.categories[key]}
                    value={this.props.categories[key]}
                    key={key}
                  />);
              })}
            </DropDown>

            <CardSection style={styles.filterBtnStyle}>
            {this.renderButton()}
            </CardSection>
      </ScrollView>
    );
  }

1 个答案:

答案 0 :(得分:2)

为什么不只使用道具将filterValue赋予子组件?

在您的HomeScreen.js中:

<HomeProject filterValue={this.state.filterValue}/>

然后您可以使用:

在HomeProject组件中访问它。
this.props.filterValue

您可以传递任何您想要的道具,并将其用于子组件中。在父组件中调用setState时,它将强制使用新值重新渲染子代。

您可以在Facebook文档上阅读有关道具的更多信息: https://facebook.github.io/react-native/docs/props