如何通过navigationOptions内部的文本输入来更新本机组件的状态?

时间:2019-11-30 00:20:23

标签: javascript reactjs react-native

我想在onChangeText事件触发时设置searchValue状态,​​并且我想使文本输入的值等于该状态的值。我试图使用导航setParam和getParams函数来做到这一点。它确实可以工作,但是问题在于该组件在每次击键时都会重新渲染两次。这是我的代码:

import React, { useState, useEffect } from "react";
import { View, StyleSheet, TextInput, FlatList } from "react-native";
import { useSelector } from "react-redux";
import { Ionicons } from "@expo/vector-icons";
import { TouchableOpacity } from "react-native-gesture-handler";
import Icon from "react-native-vector-icons/MaterialCommunityIcons";

import ProductItem from "../components/shop/ProductItem";

const SearchScreen = props => {
  const [searchValue, setSearchValue] = useState("");

  const products = useSelector(state => state.products.products);
  const promotionProducts = useSelector(
    state => state.products.promotionProducts
  );

  const textValue = props.navigation.getParam("textValue");

  useEffect(() => {
    setSearchValue(textValue);
  }, [textValue]);

  useEffect(() => {
    props.navigation.setParams({ searchValues: searchValue });
  }, [searchValue]);

  console.log(searchValue);

  return (
    <View>
      <FlatList
        columnWrapperStyle={styles.row}
        numColumns={3}
        data={products}
        keyExtractor={item => item.id}
        renderItem={itemData => (
          <ProductItem
            id={itemData.item.id}
            image={itemData.item.mainImage}
            title={itemData.item.title}
            price={itemData.item.price}
            promotion={promotionProducts}
            weightVolumeValue={itemData.item.weightVolumeValue}
            weightVolumeUnit={itemData.item.weightVolumeUnit}
            onSelect={() =>
              selectItemHandler(itemData.item.id, itemData.item.title)
            }
          />
        )}
      />
    </View>
  );
};

SearchScreen.navigationOptions = navData => {
  return {
    headerTitle: (
      <View style={styles.searchContainer}>
        <TextInput
          style={styles.searchInput}
          placeholder="ابحث عن؟"
          placeholderTextColor="white"
          value={navData.navigation.getParam("searchValues")}
          onChangeText={text =>
            navData.navigation.setParams({ textValue: text })
          }
        />
        <Icon name="magnify" size={25} style={styles.searchIcon} />
      </View>
    ),
    headerStyle: {
      backgroundColor: "#96B1AD"
    },
    headerLeft: (
      <TouchableOpacity onPress={() => navData.navigation.goBack()}>
        <Ionicons
          name="ios-arrow-back"
          size={25}
          color="white"
          style={styles.backIcon}
        />
      </TouchableOpacity>
    )
  };
};

const styles = StyleSheet.create({
  row: {
    flex: 1,
    justifyContent: "space-between"
  },
  searchContainer: {
    flexDirection: "row",
    backgroundColor: "#334B48",
    flexDirection: "row",
    flex: 1,
    alignItems: "center",
    marginBottom: 10
  },
  searchIcon: {
    color: "white",
    padding: 5
  },
  searchInput: {
    flex: 1,
    textAlign: "right",
    fontFamily: "cairo-regular",
    fontSize: 18,
    color: "white"
  },
  backIcon: {
    paddingLeft: 15,
    marginBottom: 10
  }
});

export default SearchScreen;

1 个答案:

答案 0 :(得分:0)

您将获得双重渲染,因为您将在一个useEffect中更新searchValue的更新,然后在下一个中更新导航道具。 尝试将这些更改结合在一个useEffect中,

  useEffect(() => {
    setSearchValue(textValue);
    props.navigation.setParams({ searchValues: textValue });
  }, [textValue]);