【问题标题】:React Native: change State from different componentReact Native:从不同的组件更改状态
【发布时间】:2020-10-10 11:17:27
【问题描述】:

我对 React-Native 还是很陌生。我有一个屏幕,它以 json 格式从我的服务中获取信息,然后显示数据。在那个屏幕上,我有一个组件“日历”,用户可以从中获取另一个日期。我不知道如何从该组件更新预测状态。

这是我的主屏幕:

export default function HomeScreen({ navigation }) {

  const [predictions, setPredictions] = useState([]);
  const [params, setParams] = useState({
    lang: 'en',
    date: '2020-10-11',
    sport: 'soccer'
  });

  useEffect( () => {
    loadPredictions();
  }, []);

  const loadPredictions = async () => {
    const response = await PredictionsApi.getPredictions({params});
    // console.log(response.data);
    setPredictions(response.data);
  }

  return (
    <View style={styles.main}>
        <View style={styles.container}>
          <Calendar />
          ...
        </View>
    </View>
}

这是我的日历组件:

function renderDates({props}) {
    const dates = [];
    for(let i=-2;i<4;++i) {
        var currentDate = new Date(new Date().getTime() + 24 * 60 * 60 * i * 1000);
        dates.push(
            <TouchableOpacity style={styles.dates} onPress={()=> props.setPredictions({
                lang: 'en',
                date: '2020-02-01',
                sport: 'tennis',
            })
            }>
                <Text style={styles.selected}>{Moment(currentDate).format('ddd')}{"\n"}{Moment(currentDate).format('DD')}</Text>
            </TouchableOpacity>
        );
    }
    return dates;
}

export default function Calendar({props}) {
    return (
        <View style={styles.calendarContainer}>
            ...
            <View style={styles.second}>
                {renderDates({props})}
            </View>
        </View>
    );
}

【问题讨论】:

    标签: reactjs react-native


    【解决方案1】:

    因此,我建议您在这段代码中做很多不同的事情。但是,要回答您的问题,您可以将 setPredictions 函数作为道具传递,然后在您的 Calendar 组件中使用 props.setPredictions() 调用它。

    这个想法的一个简单例子是:

    const Parent = () => {
      const parentFunction = () => console.log('Hello from parent');
    
      return <Child parentFunction={parentFunction} />;
    };
    
    
    // clicking the div in this child will call the function defined in Parent
    const Child = ({parentFunction}) => <div onClick={parentFunction}>Click me</div>;
    
    

    您也可以对在父级中设置状态的所有函数使用相同的原则。

    我会在这里停下来。如果您对这如何应用于您的代码有疑问,请询问。如果您想对其余代码提供进一步的建议,请告诉我。谢谢。

    这是我试图解决我对您的代码的一些担忧的尝试。我认为您的问题是由于道具的不正确解构引起的,而且您实际上似乎并没有在子组件中的任何位置使用设置预测或调用您的 API。我希望这是有道理的:

    // use const instead of function - more conventional
    const HomeScreen = ({navigation}) => {
      const [predictions, setPredictions] = useState([]);
      const [params, setParams] = useState({
        lang: 'en',
        date: '2020-10-11',
        sport: 'soccer',
      });
    
      useEffect(() => {
        loadPredictions();
      }, []);
    
      const loadPredictions = async () => {
        const response = await PredictionsApi.getPredictions({params});
        // console.log(response.data);
        setPredictions(response.data);
      };
    
      return (
        <View style={styles.main}>
          <View style={styles.container}>
            {/* Pass load predictions and setParams to Calendar as props */}
            <Calendar loadPredictions={loadPredictions} setParams={setParams} />
          </View>
        </View>
      );
    };
    
    // destructuring should be used to get the individual props. If you put {props} then
    // the implication is you would be using `props.props.theActualProp`
    // so either remove the curly braces or destructure the actual props
    // you want to use
    const Calendar = props => (
      <View style={styles.calendarContainer}>
        <View style={styles.second}>
          {/* pass all the props down to Dates component */}
          {/* I also changed this to an element, since there is no reason to do otherwise */}
          <Dates {...props} />
          {/* I added a button here so you can actually reload the predictions */}
          <TouchableOpacity onPress={props.loadPredictions}>Load new predictions</TouchableOpacity>
        </View>
      </View>
    );
    
    // only destructure if you are pulling individual props OUT of the `props` object
    const Dates = props => {
      // don't use for loops inside a function like this... it's cleaner to use the `map` method
      // on an array
    
      // cache the current time once per render if you need to
      const cachedTime = new Date().getTime();
    
      // I'm not sure why these particular numbers are important, or what you're trying to do here
      // I've preserverd the behaviour from your for loop, but depending on what you're trying
      // to achieve there is probably a more sensible solution to this
      return [-2, -1, 0, 1, 2, 3, 4].map(val => {
        const rowDate = new Date(cachedTime + 24 * 60 * 60 * val * 1000);
    
        return (
          <TouchableOpacity
            // add a key when mapping over an array
            key={val}
            style={styles.dates}
            onPress={() =>
              // I changed this to setParams. I think this is what you meant, since
              // setPredictions should only be form your API response?
              props.setParams({
                lang: 'en',
                date: '2020-02-01',
                sport: 'tennis',
              })
            }
          >
            <Text style={styles.selected}>
              {Moment(rowDate).format('ddd')}
              {'\n'}
              {Moment(rowDate).format('DD')}
            </Text>
          </TouchableOpacity>
        );
      });
    };
    

    【讨论】:

    • 谢谢@James,我明白了,但我在实现它时遇到了问题。我意识到 setPredictions() 正在使用 json-data 更新预测变量。所以在我的日历中,我需要用选定的日期调用 loadPredictions(),这是最难的部分:(
    • 我已经添加了我的代码版本并试图解释我所做的更改。如果您有任何问题,请告诉我。
    • 你很棒。它正在工作 :) 我刚刚删除了调用 loadPredictions() 的按钮,它是通过单击带有所选日期作为参数的日期来调用的,并且可以按我的意愿工作:)
    【解决方案2】:

    你应该先使用 setState 并阅读文档

    https://reactjs.org/docs/react-component.html#setstate

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-17
      • 2021-05-11
      相关资源
      最近更新 更多