首页 > 解决方案 > 从子组件更新父组件的状态(选项卡导航器)

问题描述

我是 React 和 React Native 的新手,我正在尝试构建一个烹饪食谱应用程序。我正在尝试从 DishIngredients.js 更新我在 DishTabNavigator.js 中的菜状态,以便我可以从 DishTabNavigator.js 将数据发送到 firebase,但是我不知道如何更新状态。我尝试提升状态,但我做不到。卡在这上面一天了。任何帮助,将不胜感激

DishTabNavigator.js

const Tab = createMaterialTopTabNavigator();

export default function MyTabs({ navigation }) {
  const [dish, setDish] = useState([{ ingredients: [] }]);
  React.useLayoutEffect(() => {
    navigation.setOptions({
      headerRight: () => (
        <TouchableOpacity style={styles.iconright}>
          <Text>Send dish to Firebase</Text>
          <FontAwesome name="save" size={24} color="black" />
        </TouchableOpacity>
      ),
    });
  });
  return (
    <Tab.Navigator>
      <Tab.Screen
        name="Ingredient"
        component={DishIngredients}
        ingredients={dish}
      />
    </Tab.Navigator>
  );
}

DishIngredients.js

class DishIngredients extends Component {
  constructor(props) {
    super(props);
    this.state = {
      ingredients: [],
      textInput: [],
    };
//Add TextInput
  addTextInput = (index) => {
    let textInput = this.state.textInput;
    textInput.push(
      <TextInput
        style={styles.textInput}
        onChangeText={(text) => this.addValues(text, index)}
      />
    );
    this.setState({ textInput });
  };

//Function to add values into the states
  addValues = (text, index) => {
    let dataArray = this.state.ingredients;
    let checkBool = false;
    if (dataArray.length !== 0) {
      dataArray.forEach((element) => {
        if (element.index === index) {
          element.text = text;
          checkBool = true;
        }
      });
    }
    if (checkBool) {
      this.setState({
        ingredients: dataArray,
      });
    } else {
      dataArray.push({ text: text, index: index });
      this.setState({
        ingredients: dataArray,
      });
    }
  };

  //function to console the output
  getValues = () => {
    console.log("Data", this.state.ingredients);
    this.props.ingredients = this.state.ingredients;
    console.log(this.props.ingredients);
  };

  render() {
    return (
      <View>
        <View style={styles.icon}>
          <View style={{ margin: 10 }}>
            <TouchableOpacity>
              <Ionicons
                name="add"
                size={24}
                color="black"
                onPress={() => this.addTextInput(this.state.textInput.length)}
              />
            </TouchableOpacity>
          </View>
          <View style={{ margin: 10 }}>
            <Button title="Remove" onPress={() => this.removeTextInput()} />
          </View>
        </View>
        {this.state.textInput.map((value) => {
          return value;
        })}
        <Button title="Get Values" onPress={() => this.getValues()} />
      </View>
    );
  }
}

export default DishIngredients;

标签: javascriptreactjsreact-native

解决方案


你可以使用反应上下文

const DishContext = React.createContext({
  dish: [],
  setDish: () => {},
});

export const useDishContext = () => React.useContext(DishContext);

export const AppDishProvider = ({children}) => {
  const [dish, setDish] = useState([{ingredients: []}]);

  const defaultDish = {
    dish,
    setDish,
  };

  return (
    <DishContext.Provider value={defaultDish}>{children}</DishContext.Provider>
  );
};

然后

/** Wrap your TabNavigator with AppDishProvider */
<AppDishProvider>
  <YourTabNavigator />
</AppDishProvider>

然后

/**
 * In DishIngredients, or your TabNavigator...
 * You get access to dish-state, and setDish using your
 * custom-hook `useDishContext`
 */

 const { dish, setDish } = useDishContext();

如果你使用基于类的组件

class DishIngredient extends React.Component {
  static contextType = DishContext;

  /**
   * Current context-value could be accessed by
   * `this.context`
   */

  render() {
    const {dish, setDish} = this.context;
    /** .... */
  }
}

假设你没有在你的应用程序中连接 redux ...... ReactContext 是你要走的路......


推荐阅读