热从另一个组件中获取选定的值?

Hot to get selected value from another component?

我用 react-native <Modal /> 创建了一个组件 Confirm.js,它有两个 DropDownMenu 和两个 <Button />

我希望用户单击是 <Button /> 然后我可以获得 DropDownMenu onOptionSelected 值。我想我应该使用 this.props 但我不知道该怎么做。

我想从 Confirm.js

中获取 MainActivity.js 中的值

如有任何建议,我们将不胜感激。提前致谢。

这是我的 MainActivty.js 点击 <Button /> 显示 <Confirm />:

    import React, { Component } from 'react';
    import { Confirm } from './common';
    import { Button } from 'react-native-elements';
    class MainActivity extends Component {

      constructor(props) {
        super(props);
        this.state = { movies: [], content: 0, showModal: false, isReady: false };
      }

      // close the Confirm
      onDecline() {
        this.setState({ showModal: false });   
      }

      render() {
         return (
           <View style={{ flex: 1 }}> 
              <Button
                 onPress={() => this.setState({ showModal: !this.state.showModal })}
                 backgroundColor={'#81A3A7'}
                 containerViewStyle={{ width: '100%', marginLeft: 0 }}
                 icon={{ name: 'search', type: 'font-awesome' }}
                 title='Open the confirm' 
               />

               <Confirm
                 visible={this.state.showModal}
                 onDecline={this.onDecline.bind(this)}
                >
                </Confirm>      
            </View>
         );
      }
}

export default MainActivity;

Confirm.js:

import React from 'react';
import { Text, View, Modal } from 'react-native';
import { DropDownMenu } from '@shoutem/ui';
import TestConfirm from './TestConfirm';
import { CardSection } from './CardSection';
import { Button } from './Button';
import { ConfirmButton } from './ConfirmButton';

const Confirm = ({ children, visible, onAccept, onDecline }) => {

  const { containerStyle, textStyle, cardSectionStyle } = styles;

  return (
    <Modal
      visible={visible}
      transparent
      animationType="slide"
      onRequestClose={() => {}}
    >
      <View style={containerStyle}>
        <CardSection style={cardSectionStyle}>
          {/* Here is my DropDownMenu */}
          <TestConfirm />
        </CardSection>

        <CardSection>
          <ConfirmButton onPress={onAccept}>Yes</ConfirmButton>
          <ConfirmButton onPress={onDecline}>No</ConfirmButton>
        </CardSection>
      </View>
    </Modal>
  );
};

const styles = {
  cardSectionStyle: {
    justifyContent: 'center'
  },
  textStyle: {
    flex: 1,
    fontSize: 18,
    textAlign: 'center',
    lineHeight: 40
  },
  containerStyle: {
    backgroundColor: 'rgba(0, 0, 0, 0.75)',
    position: 'relative',
    flex: 1,
    justifyContent: 'center'
  },
  buttonStyle: {
    flex: 1,
    alignSelf: 'stretch',
    backgroundColor: '#fff',
    borderRadius: 5,
    borderWidth: 1,
    borderColor: '#007aff',
    marginLeft: 5,
    marginRight: 5
  }
};

export { Confirm };

TestConfirm.js

import React, { Component } from 'react';
import { View } from 'react-native';
import { DropDownMenu, Title, Image, Text, Screen, NavigationBar } from '@shoutem/ui';
import { 
  northCities,
  centralCities,
  southCities,
  eastCities,
  islandCities
} from './CityArray';

class TestConfirm extends Component {

    constructor(props) {
        super(props);
        this.state = {
          zone: [
            {
              id: 0,
              brand: "North",
              children: northCities
              },
            {
              id: 1,
              brand: "Central",
              children: centralCities
            },
            {
              id: 2,
              brand: "South",
              children: southCities
            },
            {
              id: 3,
              brand: "East",
              children: eastCities
            },
            {
              id: 4,
              brand: "Island",
              children: islandCities
            },
          ],
        }
      }

  render() {
    const { zone, selectedZone, selectedCity } = this.state

    return (
      <Screen>
        <DropDownMenu
            style={{
              selectedOption: {
                marginBottom: -5
              }
            }}
            styleName="horizontal"
            options={zone}
            selectedOption={selectedZone || zone[0]}
            onOptionSelected={(zone) => 
                this.setState({ selectedZone: zone, selectedCity: zone.children[0] })}
            titleProperty="brand"
            valueProperty="cars.model"
        />
       <DropDownMenu
            style={{
              selectedOption: {
                marginBottom: -5
              }
            }}
            styleName="horizontal"
            options={selectedZone ? selectedZone.children : zone[0].children} // check if zone selected or set the defaul zone children
            selectedOption={selectedCity || zone[0].children[0]} // set the selected city or default zone city children
            onOptionSelected={(city) => this.setState({ selectedCity: city })} // set the city on change
            titleProperty="cnCity"
            valueProperty="cars.model"
        />
      </Screen>
    );
  }
}

export default TestConfirm;

如果我 console.log DropDownMenu onOptionSelected 值像城市,它将是

{cnCity: "宜蘭", enCity: "Ilan", id: 6}

我想从 MainActivity.js

得到 enCity

ConfirmButton.js:

import React from 'react';
import { Text, TouchableOpacity } from 'react-native';

const ConfirmButton = ({ onPress, children }) => {
  const { buttonStyle, textStyle } = styles;

  return (
    <TouchableOpacity onPress={onPress} style={buttonStyle}>
      <Text style={textStyle}>
        {children}
      </Text>
    </TouchableOpacity>
  );
};

const styles = {
  { ... }
};

export { ConfirmButton };

您可以通过 props 将函数传递给相关组件,并且 运行 该函数具有您从下拉列表中获得的所需参数。因为你在树中有几个组件,所以它会有点难以理解,但如果你明白了,我相信你会让它变得更简单。此外,在熟悉这种行为和 React 风格编码后,您可以将项目升级到某种全局状态管理,如 redux、flux 或 mobx。

示例 (删除了不相关的部分)

class MainActivity extends Component {
  onChangeValues = (values) => {
    // do some stuf with the values
    // value going to have 2 properties
    // { type: string, value: object }
    const { type, value } = values;
    if(type === 'zone') {
      // do something with the zone object
    } else if(type === 'city') {
      // do something with the city object
    }

  }
  render() {
    return(
      <Confirm onChangeValues={this.onChangeValues} />
    )
  }
}

const Confirm = ({ children, visible, onAccept, onDecline, onChangeValues }) => {
  return(
    <TestConfirm onChangeValues={onChangeValues} />
  )
}

class TestConfirm extends Component {
  render() {
    return(
      <Screen>
        <DropDownMenu
          onOptionSelected={(zone) => {
            // run passed prop with the value
            this.props.onChangeValues({type: 'zone', value: zone});
            this.setState({ selectedZone: zone, selectedCity: zone.children[0] });
          }}              
        />
        <DropDownMenu 
          onOptionSelected={(city) => {
            // run passed prop with the value
            this.props.onChangeValues({type: 'city', value: city});
            this.setState({ selectedCity: city })
          }}              
        />
      </Screen>
    )
  }
}