与ListView不同,我们可以更新this.state.datasource。是否有任何方法或示例来更新FlatList或重新渲染它?
我的目标是在用户按下按钮时更新文本值...
renderEntries({ item, index }) {
return(
<TouchableHighlight onPress={()=> this.setState({value: this.state.data[index].value+1})>
<Text>{this.state.data[index].value}</Text>
</TouchableHighlight>
)
}
<FlatList
ref={(ref) => { this.list = ref; }}
keyExtractor={(item) => item.entry.entryId}
data={this.state.data}
renderItem={this.renderEntries.bind(this)}
horizontal={false} />
答案 0 :(得分:123)
使用FlatList组件上的extraData
属性。
正如文件所述:
通过将
extraData={this.state}
传递给FlatList
,我们确保FlatList
本身会在state.selected
更改时重新呈现。如果没有设置此道具,FlatLis
t就不会知道需要重新渲染任何项目,因为它也是PureComponent
并且道具比较不会显示任何更改。
答案 1 :(得分:23)
快速简单的解决方案尝试:
将额外数据设置为布尔值。
=而额外{this.state.refresh}
当您想重新渲染/刷新列表
时,切换布尔状态的值this.setState({
refresh: !this.state.refresh
})
答案 2 :(得分:14)
哦,这很简单,只需使用extraData
您会看到额外数据在幕后工作的方式是 FlatList 或 VirtualisedList 只是通过普通onComponentWillReceiveProps
方法检查wether that object has changed。
所以你要做的就是确保你给extraData
改变了一些东西。
这就是我的所作所为:
我正在使用immutable.js所以我所做的就是传递一个包含我想要观看的内容的Map(不可变对象)。
<FlatList
data={this.state.calendarMonths}
extraData={Map({
foo: this.props.foo,
bar: this.props.bar
})}
renderItem={({ item })=>((
<CustomComponentRow
item={item}
foo={this.props.foo}
bar={this.props.bar}
/>
))}
/>
这样,当this.props.foo
或this.props.bar
发生变化时,我们的CustomComponentRow
会更新,因为不可变对象将与之前的对象不同。
答案 3 :(得分:4)
如果您要使用Button,则可以使用onPress中的setState更新数据。然后,SetState将重新渲染FlatList。
答案 4 :(得分:4)
好的。我刚刚发现,如果我们希望FlatList知道数据属性之外的数据更改,我们需要将其设置为extraData,所以我现在就这样:
<FlatList data={...} extraData={this.state} .../>
请参阅:DRF Source-Code
答案 5 :(得分:2)
我通过添加public class DataAccess {
private static AsyncHttpClient client = new AsyncHttpClient();
public static void get(Context context, String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
client.get(getAbsoluteUrl(url), params, responseHandler);
}
public static void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
client.post(getAbsoluteUrl(url), params, responseHandler);
}
private static void start() {
}
private static String getAbsoluteUrl(String relativeUrl) {
return Settings.serverLink + relativeUrl;
}
}
解决了此问题,请查看下面的代码以获取更多详细信息
extraData={this.state}
答案 6 :(得分:1)
这里只是先前答案的扩展。 确保两部分,请确保添加extraData且keyExtractor是唯一的。如果您的keyExtractor是常量,则不会触发重新渲染。
<FlatList
data={this.state.AllArray}
extraData={this.state.refresh}
renderItem={({ item,index })=>this.renderPhoto(item,index)}
keyExtractor={item => item.id}
>
</FlatList>
答案 7 :(得分:1)
经过大量搜索和寻找真实的答案之后,我终于得到了我认为是最好的答案:
<FlatList
data={this.state.data}
renderItem={this.renderItem}
ListHeaderComponent={this.renderHeader}
ListFooterComponent={this.renderFooter}
ItemSeparatorComponent={this.renderSeparator}
refreshing={this.state.refreshing}
onRefresh={this.handleRefresh}
onEndReached={this.handleLoadMore}
onEndReachedThreshold={1}
extraData={this.state.data}
removeClippedSubviews={true}
**keyExtractor={ (item, index) => index }**
/>
.....
我的主要问题是(KeyExtractor) 我没有像这样使用它。 不起作用:keyExtractor = {(项目)=> item.ID} 在我改变这个之后,它就像魅力一样工作 我希望这对某人有帮助。
答案 8 :(得分:0)
const [itemSelected, setItemSelected] = setState(null);
....
const FlatListItem = (item) => {
return (
<TouchableOpacity onPress={() => setItemSelected(item.id)}>
<View style={ (itemSelected === item.id) ? style.itemWrapperActive : style.itemWrapper }>
<Text>{ item.label }</Text>
</View>
</TouchableOpacity>
)
}
....
<FlatList
ItemSeparatorComponent={() => <View style={{ width: 20 }} />}
data={ flatListData }
renderItem={ ({item}) => FlatListItem(item) }
keyExtractor={ (item) => item.id }
extraData={ itemSelected }
/>
答案 9 :(得分:0)
我正在使用功能组件,因为我正在使用带有 redux 数据的 Flatlist。 我正在使用 Redux 商店管理所有状态。 这里是api调用后更新Flatlist数据的解决方法。
我第一次是这样做的:-
public class UserDao {
private Connection con;
public UserDao(Connection con) {
this.con = con;
}
// method to insert data of user in database
public boolean saveUser(User user)
{
boolean f=false;
try {
String query = "insert into user(name,email,password,gender,about) values(?,?,?,?,?)";
PreparedStatement pstmt = this.con.prepareStatement(query);
pstmt.setString(1, user.getName());
pstmt.setString(2, user.getEmail());
pstmt.setString(3, user.getPassword());
pstmt.setString(4, user.getGender());
pstmt.setString(5, user.getAbout());
pstmt.executeUpdate();
f=true;
} catch (Exception e)
{
e.printStackTrace();
}
return f;
}
// Get User by User E-Mail & Password
public User getUserByEmailAndPassword(String email,String password)
{
User user=null;
try {
String query ="select * from user Where email=?,password=?";
PreparedStatement pstmt = con.prepareStatement(query);
pstmt.setString(1, email);
pstmt.setString(2, password);
ResultSet set =pstmt.executeQuery();
if(set.next())
{
user = new User();
// Data From DB
String name = set.getString("name");
// Set in User Obj
user.setName(name);
user.setId(set.getInt("id"));
user.setEmail(set.getString("email"));
user.setPassword(set.getString("[password"));
user.setGender(set.getString("gender"));
user.setAbout(set.getString("about"));
user.setDateTime(set.getTimestamp("regdate"));
user.setProfile(set.getString("profile"));
}
} catch (Exception e) {
e.printStackTrace();
}
return user;
}
}
但数据根本没有重新渲染我的 Flatlist 数据。
作为我喜欢的解决方案如下:-
const DATA = useSelector((state) => state.address.address);
<FlatList
style = {styles.myAddressList}
data = {DATA}
renderItem = {renderItem}
keyExtractor = {item => item._id}
ListEmptyComponent = {EmptyList}
ItemSeparatorComponent={SeparatorWhite}
extraData = {refresh}
/>
我将 Redux 状态直接传递给 Flatlist 数据源,而不是将其分配给变量。
谢谢。
答案 10 :(得分:0)
在此示例中,要强制重新渲染,只需更改变量machine
const [selected, setSelected] = useState(machine)
useEffect(() => {
setSelected(machine)
}, [machine])
答案 11 :(得分:0)
在react-native-flatlist中,它们是称为ExtraData的属性。将以下行添加到您的单位列表中。
<FlatList
data={data }
style={FlatListstyles}
extraData={this.state}
renderItem={this._renderItem}
/>
答案 12 :(得分:0)
只需使用:
onRefresh={true}
在flatList
组件内部。
答案 13 :(得分:0)
如果我们希望FlatList 了解道具和州的数据更改,我们可以构造一个同时引用道具和状态的对象并刷新该公寓表。
const hasPropOrStateChange = { propKeyToWatch: this.props, ...this.state};
<FlatList data={...} extraData={this.hasPropOrStateChange} .../>
文档:https://facebook.github.io/react-native/docs/flatlist#extradata
答案 14 :(得分:0)
通过您在extraData
您可以发挥创造力。
例如,如果您正在处理带有复选框的更改列表。
<FlatList
data={this.state.data.items}
extraData={this.state.data.items.length * (this.state.data.done.length + 1) }
renderItem={({item}) => <View>
答案 15 :(得分:0)
对我来说,诀窍是extraData并再次深入到项目组件
state = {
uniqueValue: 0
}
<FlatList
keyExtractor={(item, index) => item + index}
data={this.props.photos}
renderItem={this.renderItem}
ItemSeparatorComponent={this.renderSeparator}
/>
renderItem = (item) => {
if(item.item.selected) {
return ( <Button onPress={this.itemPressed.bind(this, item)}>Selected</Button> );
}
return ( <Button onPress={this.itemPressed.bind(this, item)}>Not selected</Button>);
}
itemPressed (item) {
this.props.photos.map((img, i) => {
if(i === item.index) {
if(img['selected') {
delete img.selected;
} else {
img['selected'] = true;
}
this.setState({ uniqueValue: this.state.uniqueValue +1 });
}
}
}
答案 16 :(得分:0)
我已将FlatList
替换为SectionList
,并且在状态更改时正确更新。
<SectionList
keyExtractor={(item) => item.entry.entryId}
sections={section}
renderItem={this.renderEntries.bind(this)}
renderSectionHeader={() => null}
/>
唯一需要记住的是section
有差异结构:
const section = [{
id: 0,
data: this.state.data,
}]
答案 17 :(得分:-1)
Flatlist的extraData对我不起作用,我碰巧正在使用redux的道具。这听起来与ED209答复中的评论类似。收到道具后,我最终手动调用了setState。
componentWillReceiveProps(nextProps: StateProps) {
if (this.props.yourProp != null && nextProps.yourProp) {
this.setState({ yourState: processProp(nextProps.yourProp) });
}
}
<FlatList
data={this.state.yourState}
extraData={this.state.yourState}
/>
对于那些使用> React 17的用户,请使用getDerivedStateFromProps