我要在“浏览”组件中获取api(makeup API)并在“浏览”按钮中也使用它。 我将品牌作为ExploreButtons中的按钮。当我在ExploreButtons中的FlatList元素中单击按钮时,我想在ExploreButtons中的第二个FlatList中查看来自api的图像。单击按钮时,componentDidMount是否可以重新渲染?
import React, { Component } from 'react'
import { View } from 'react-native'
import ExploreButtons from './ExploreButtons'
export default class Explore extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
makeupApi: 'http://makeup-api.herokuapp.com/api/v1/products.json',
}
}
callbackFunction = (item) => {
this.setState({
makeupApi: 'http://makeup-api.herokuapp.com/api/v1/products.json?brand=' + item,
})
}
async componentDidMount() {
try {
const response = await fetch(this.state.makeupApi);
const responseJson = await response.json();
this.setState({
isLoading: false,
dataSource: responseJson,
}, function () {
});
const reformattedArray = this.state.dataSource.map(obj => {
var rObj = {};
rObj = obj.brand;
return rObj;
});
this.setState({
duplicatesRemoved: reformattedArray.filter((item, index) => reformattedArray.indexOf(item) === index)
})
}
catch (error) {
console.error(error);
}
};
render() {
console.log(this.state.makeupApi)
return (
<View style={{ flex: 1 }}>
<ExploreButtons
api={this.state.dataSource}
removedDuplicatesFromAPI={this.state.duplicatesRemoved}
parentCallback={this.callbackFunction}
makeupApi= {this.state.makeupApi} />
</View>
)
}
}
export default class ExploreButtons extends Component {
getBrandImages = (item) => {
this.props.parentCallback(item)
}
render() {
return (
<View style={{ flex: 1 }}>
<View>
<FlatList
horizontal
showsHorizontalScrollIndicator={false}
data={this.props.removedDuplicatesFromAPI}
renderItem={({ item }) =>
<TouchableOpacity
style={styles.exploreButtons}
onPress={() => {
this.getBrandImages(item)
}}
>
<Text>{item}</Text>
</TouchableOpacity>
}
keyExtractor={item => item}
/>
</View>
<View>
<FlatList
data={this.props.api}
renderItem={({ item }) =>
<View>
<Image source={{ uri: item.image_link }}
style={{
alignSelf: "center",
width: '100%',
height: 300,
}} />
</View>
}
keyExtractor={item => item.id.toString()} />
</View>
</View>
)
}
}
答案 0 :(得分:2)
您可以将所有逻辑放在componentDidMount
中的另一个函数中,并在调用回调时调用它。作为第一种非常粗略的方法,它将起作用:
注意:您实际上不需要状态中的API URL,只需将项目放在状态中并根据其构造URL。
import React, { Component } from 'react';
import { View } from 'react-native';
import ExploreButtons from './ExploreButtons';
export default class Explore extends Component {
API_URL = 'http://makeup-api.herokuapp.com/api/v1/products.json';
constructor(props) {
super(props);
this.state = {
isLoading: true,
item: null,
dataSource: null,
duplicatesRemoved: [],
};
}
getAPIURL(item) {
if(!item){
return API_URL
}
return `${API_URL}?brand=${item}`;
}
async fetchData(item) {
try {
const url = getAPIURL(item);
const response = await fetch(url);
const responseJson = await response.json();
this.setState({
isLoading: false,
dataSource: responseJson,
item,
});
const reformattedArray = responseJSON.map(({ brand }) => brand);
this.setState({
duplicatesRemoved: reformattedArray.filter(
(item, index) => reformattedArray.indexOf(item) === index,
),
});
} catch (error) {
console.error(error);
}
}
async componentDidMount() {
fetchData();
}
render() {
const { dataSource, duplicatesRemoved, item } = this.state;
return (
<View style={{ flex: 1 }}>
<ExploreButtons
api={dataSource}
removedDuplicatesFromAPI={duplicatesRemoved}
parentCallback={this.fetchData}
makeupApi={getURL(item)}
/>
</View>
);
}
}
export default class ExploreButtons extends Component {
getBrandImages = item => {
this.props.parentCallback(item);
};
render() {
const { removedDuplicatesFromAPI, api } = this.props;
return (
<View style={{ flex: 1 }}>
<View>
<FlatList
horizontal
showsHorizontalScrollIndicator={false}
data={removedDuplicatesFromAPI}
renderItem={({ item }) => (
<TouchableOpacity
style={styles.exploreButtons}
onPress={() => {
this.getBrandImages(item);
}}
>
<Text>{item}</Text>
</TouchableOpacity>
)}
keyExtractor={item => item}
/>
</View>
<View>
<FlatList
data={api}
renderItem={({ item }) => (
<View>
<Image
source={{ uri: item.image_link }}
style={{
alignSelf: 'center',
width: '100%',
height: 300,
}}
/>
</View>
)}
keyExtractor={item => item.id.toString()}
/>
</View>
</View>
);
}
}
答案 1 :(得分:0)
如何使componentDidMount再次呈现?
不确定您的意思,但是我想您要问的是How can I make componentDidMount *run* again?
,为此,您需要在callbackFunction
中具有相同的代码才能再次运行它。 componentDidMount
仅在组件首次渲染后运行。
还要注意,如果要重新渲染FlatList
,则需要传递extraData
,以便知道它需要重新渲染。