我有动态表单,当用户开始在第一个表单TextInput上键入时,用户可以在其中添加表单和删除表单,它将根据输入给出建议。现在的问题是,当用户开始在第一个TextInput字段上键入内容时,它将获得建议,但是当用户通过单击addForm按钮添加另一个表单时,以及当用户开始在新表单上键入内容时,它将获得建议,但是同时在第一个表单中,它也会开始给出建议,如果有三种形式,则给出相同的建议;如果用户开始输入一种形式,它将开始为所有三种形式给出建议。我想说,如果用户键入任何一种形式,它将在所有窗体上给出建议。
我想如果用户使用第一种形式,那么它将仅针对第一种形式给出建议,而不针对第二种形式。如果用户使用第二种形式,则只会在第二种形式上得到建议,而不是第一种形式。
您可以在上图中看到,即使我在第二个表单上键入,它也为两种表单都提供了建议
import React, { PureComponent } from 'react'
import {
View,
TextInput,
ScrollView,
KeyboardAvoidingView,
StyleSheet,
Picker,
ListView,
FlatList
} from 'react-native'
import { getStockItems } from "../../actions/getIndentsAction";
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { TouchableOpacity } from 'react-native-gesture-handler';
import { CardSection, Text, Button, Block, Input } from '../../components';
import { theme } from '../../constants';
import { MaterialIcons,AntDesign,Entypo } from '@expo/vector-icons';
import { CardItem,Content, ListItem,Icon,Card, Left, Body, Right } from 'native-base';
class IndentForm extends PureComponent {
static navigationOptions = ({ navigation }) => {
const { params = {} } = navigation.state;
return {
headerRight: (
<TouchableOpacity onPress={() => params.handleSave()}>
<AntDesign
name='plus'
style={{ paddingRight:10}}
size={25}
color='white'
/>
</TouchableOpacity>
)
};
};
constructor(props) {
super(props);
this.state = {
companyName:'',
formFields:[{
Item_Description:'',
Quantity:'',
}],
searchedForm:[]
};
}
componentDidMount() {
this.props.navigation.setParams({ handleSave: this.addInput});
this.props.getStockItems()
}
//add dynamic form
addInput = () => {
const existingFormFields = this.state.formFields.map(fields => ({...fields}))
const allFormFieldsAfterAddingNew = [...existingFormFields, {Item_Description: '', Quantity:''}]
this.setState({formFields: allFormFieldsAfterAddingNew})
}
//remove dynamic form
removeInput = index => () => {
this.setState({
formFields: this.state.formFields.filter((s, sidx) => index !== sidx)
});
};
//on Item Descriptionchange
onItemDescriptionChange = (text, index) => {
const { stocks } = this.props.indent;
const existingFormFields = this.state.formFields.map(fields => ({...fields}))
let targetField = {...existingFormFields[index]}
targetField.Item_Description = text
existingFormFields[index] = targetField
var searchedForm = stocks.filter(function(stock) {
return stock.Item.toLowerCase().indexOf(text.toLowerCase()) > -1;
});
this.setState({searchedForm: searchedForm , formFields: existingFormFields})
}
//on Quantity change
onQuantityChange = (text, index) => {
const existingFormFields = this.state.formFields.map(fields => ({...fields}))
let targetField = {...existingFormFields[index]}
targetField.Quantity = text
existingFormFields[index] = targetField
this.setState({formFields: existingFormFields})
}
itemSelect = (item,index) => {
const existingFormFields = this.state.formFields.map(fields => ({...fields}))
let targetField = {...existingFormFields[index]}
targetField.Item_Description = item.Item
existingFormFields[index] = targetField
this.setState({searchedForm:[], formFields:existingFormFields})
console.log("hello" + " " + item.Item + " " + index);
}
onsubmit = () => {
const data = {
companyName:this.state.companyName,
formFields:this.state.formFields
}
console.log(data)
}
render() {
const { stocks } = this.props.indent;
return (
<KeyboardAvoidingView style={{flex:1, justifyContent:"center"}} behavior="padding">
<ScrollView
showsVerticalScrollIndicator={false}
>
<Block padding={[5]}>
<Card>
<Picker
style={{flex:1}}
selectedValue={this.state.companyName}
onValueChange={(companyName)=>this.setState({companyName:companyName})}
>
<Picker.Item label='developer' value="0" />
<Picker.Item label="Developer" value="Developer" />
<Picker.Item label="Junior Develope" value="Junior Develope" />
</Picker>
</Card>
{
this.state.formFields.map((field, index) => {
return(
<Card key={index} >
<CardItem bordered>
<Left>
<Text bold>Items no : {index + 1}</Text>
</Left>
<Right>
<TouchableOpacity
onPress={this.removeInput(index)}
>
<Entypo
name="cross"
size={20}
color='#E46932'
/>
</TouchableOpacity>
</Right>
</CardItem>
<Block padding={[0, theme.sizes.base]}>
<Block>
<Input
label="description"
style={[styles.input]}
value={field.Item_Description}
onChangeText={(text)=> this.onItemDescriptionChange(text, index)}
/>
<FlatList
data={this.state.searchedForm}
keyExtractor={(ItemId,index) => index.toString()}
renderItem={({item,index})=>(
<ListItem
button={true}
key={index}
onPress={()=>this.itemSelect(item,index)}
>
<Text bold>{item.Item}</Text>
</ListItem>
)}
/>
</Block>
<Input
label="Quantity"
style={[styles.input]}
value={field.Quantity}
onChangeText={(text)=> this.onQuantityChange(text, index)}
/>
</Block>
</Card>
)
})
}
<Block padding={[0, theme.sizes.base * 1.5]}>
<Button
style={styles.submitInput}
onPress={this.onsubmit}>
<Text bold white center>Submit</Text>
</Button>
</Block>
</Block>
</ScrollView>
</KeyboardAvoidingView>
)
}
}
IndentForm.propTypes = {
getStockItems: PropTypes.func.isRequired,
indent: PropTypes.object.isRequired,
};
const mapStateToProps = state => ({
indent: state.indent,
errors:state.errors
});
export default connect(
mapStateToProps,
{
getStockItems,
}
)(IndentForm);
const styles = StyleSheet.create({
input: {
borderRadius: 0,
borderWidth: 0,
borderBottomColor: theme.colors.gray2,
borderBottomWidth: StyleSheet.hairlineWidth,
marginLeft:5
},
submitInput:{
backgroundColor:"#2ecc71"
},
addInput:{
backgroundColor:"white"
},
addButton:{
alignItems:"flex-end",
position:"absolute",
right:20,
bottom:20,
},
searchBarContainerStyle: {
marginBottom: 10,
flexDirection: "row",
height: 40,
shadowOpacity: 1.0,
shadowRadius: 5,
shadowOffset: {
width: 1,
height: 1
},
backgroundColor: "rgba(255,255,255,1)",
shadowColor: "#d3d3d3",
borderRadius: 10,
elevation: 3,
marginLeft: 10,
marginRight: 10
},
selectLabelTextStyle: {
color: "#000",
textAlign: "left",
width: "99%",
padding: 10,
flexDirection: "row"
},
placeHolderTextStyle: {
color: "#D3D3D3",
padding: 10,
textAlign: "left",
width: "99%",
flexDirection: "row"
},
dropDownImageStyle: {
marginLeft: 10,
width: 10,
height: 10,
alignSelf: "center"
},
pickerStyle: {
marginLeft: 18,
elevation:3,
paddingRight: 25,
marginRight: 10,
marginBottom: 2,
shadowOpacity: 1.0,
shadowOffset: {
width: 1,
height: 1
},
borderWidth:1,
shadowRadius: 10,
backgroundColor: "rgba(255,255,255,1)",
shadowColor: "#d3d3d3",
borderRadius: 5,
flexDirection: "row"
}
})
答案 0 :(得分:0)
当您执行 addInput 时,它将为每个输入添加新的FlatList。但是,FlatList的数据由单个状态管理,该状态为 this.state.searchedForm 。
因此,每当调用 onItemDescriptionChange 时,它都会更新 searchedForm 状态,并且所有FlatList都会反映该更改。
要解决此问题,您要么必须将FlatList数据保留在 formFields 状态内作为一个键,要么可以为每个输入管理不同的状态。