我对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>
);
}
答案 0 :(得分:0)
您应该使用setState并先阅读文档
答案 1 :(得分:0)
因此,我建议您在这段代码中做很多事情。但是,要回答您的问题,您可以向下传递setPredictions
函数作为道具,然后在props.setPredictions()
组件中使用Calendar
进行调用。
这个想法的一个简单例子是:
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>
);
});
};