我是React的新手,我正在React中设计一个有多个字段的提交表单。它有一些Textfield输入框和一个Tags输入功能。用户在字段中输入他们的信息,在最后,信息必须显示在一个确认页面上。现在我所有的信息都显示出来了,除了标签(来自标签输入)。问题出在哪里?
表格(AdditionalInfo.js)
export const TagsInput = props => {
const [Tags, setTags] = React.useState(props.Tags)
const removeTags = indexToRemove => {
setTags([...Tags.filter((_, index) => index !== indexToRemove)])
}
const addTags = event => {
if (event.target.value !== '') {
setTags([...Tags, event.target.value])
props.selectedTags([...Tags, event.target.value])
event.target.value = ''
}
}
return (
<div className='tags-input'>
<ul id='tags'>
{Tags.map((Tag, index) => (
<li key={index} className='tag'>
<span className='tag-title'>{Tag}</span>
<span
className='tag-close-icon'
onClick={() => removeTags(index)}
>
x
</span>
</li>
))}
</ul>
<input
type='text'
onKeyUp={event => event.key === 'Enter' ? addTags(event) : null}
placeholder='Press enter to add tags'
/>
</div>
)
}
export class AdditionalInfo extends Component {
continue = e => {
e.preventDefault();
this.props.nextStep();
};
back = e => {
e.preventDefault();
this.props.prevStep();
};
render() {
const {values, handleChange} = this.props
const selectedTags = Tags => {
console.log(Tags)
}
return (
<Container className='ContainerA'>
<Row>
<Col className='ACol'>
<br />
<br />
<div>
<TagsInput selectedTags={selectedTags} Tags={['Nodejs', 'MongoDB']} onChange={handleChange('Tags')}
defaultValue={values.Tags} />
</div>
<Row>
<Col xs='6' sm='4'>
<TextField
placeholder="Country"
label="Country"
onChange={handleChange('Country')}
defaultValue={values.Country}
margin="normal"
fullWidth="true"
id="outlined-basic"
variant="outlined"
required
/>
....
<div className='buttons-container' style={{position:'relative',bottom:'20px'}}>
<button onClick={this.back} className='previous'>قبلی</button>
<button form='my-form' type='submit' onClick={this.continue} className='next'>ادامه</button>
</div>
主表格持有人
//AdditionalInfo.js is used here
class CreateJob extends Component {
state = {
step:1,
Title:'',
requirements:'',
Country:'',
Region:'',
Zipcode:'',
Benefits:'',
Company:'',
InternalCode:'',
Details:'',
Tags:[],
Address:'',
Department:'',
Salary:''
}
nextStep =() => {
const {step} = this.state
this.setState({
step: step + 1
})
}
prevStep =() => {
const {step} = this.state
this.setState({
step: step - 1
})
}
handleChange = input => e => {
this.setState({ [input]: e.target.value });
};
render () {
const { step } = this.state
const {Title,Benefits,Company,InternalCode,Detailss,Tags,Address,Department,Salary,requirements,Country,Region,Zipcode } = this.state;
const values ={Title,Benefits,Company,InternalCode,Detailss,Tags,Address,Department,Salary,requirements,Country,Region,Zipcode}
return (
<div>
........
{(()=>{
switch (step) {
case 1:
return(
<AdditionalInfo
nextStep={this.nextStep}
handleChange={this.handleChange}
values={values}
/>
)
.........
而这是确认页
//it uses the main form holder component info too
export class Confirmation extends Component {
continue = e => {
e.preventDefault();
this.props.nextStep();
};
back = e => {
e.preventDefault();
this.props.prevStep();
};
render () {
const {
values: {
Title, Benefits,
Company, InternalCode, Detailss, Department,Tags, Salary,requirements,Zipcode,
Country,Region
}
} = this.props
return (
....
<div className='content'>
<Container>
<Row>
<Col xs='6' sm='4' className='TextContent'>
<Row className='TextInside'> {Salary} : حقوق پیشنهادی</Row>
<Row> زیپ کد : {Zipcode}</Row>
<Row> کشور : {Country} </Row>
..
</Col>
<Col xs='6' sm='4' className='TextContent'>
...
<Row> تگ ها : {Tags}</Row>
对不起,代码太长了,但我不明白为什么{国家}的信息会被删除。(例如)显示在这个确认页面中,但我的TagsInput {Tags}中的标签却没有显示出来(即使它们正确地登录到Console中)我的错误在哪里?
您的 AdditionalInfo
组件将其每个输入与 handleChange
props,它是由父代传递给它的。当一个字段被更新时,父代就会知道它。
您的 TagsInput
组件将标签列表存储在其 自己 状态(useState钩子)。它从来不会通知父体它的任何变化。
之后,当你的父代(大概是,没有显示)调用了 ConfirmationPage
它不知道输入的标签,但它知道其他信息,因为它被告知了这些信息。
相反,跟踪父代的标签列表,并将当前的标签列表(以及 "addTag "和 "removeTag "处理程序)传递给子代。
更新
我已经编辑了你的沙盒,展示了一个工作实例。请注意,我确实不得不删除了很多对外部文件的引用,以使其编译,所以在未来,你可能会想在发布沙盒之前,将你的代码剥离到你的确切问题上。
https:/codesandbox.iostagger-u8fs5
一些说明。
updateParent
函数,该函数在每次添加或删除标签时都会被调用。handleChange
函数不能用于标签,因为你设置了寻找 e.target.value
而在这种情况下,我们是直接向它发送一个值的数组,而不是一个带值的事件。我在这里添加了一个 handleChangeRaw
函数,允许这样做。setTags
),然后有 updateParent
函数直接引用该状态,因为它将落后于一个渲染(即落后于一个标签)。.join(',')
到您的标签输出中;否则,它只是试图将元素组成一个字符串,将这些词一起运行。所以总结起来,缺失的一步确实是你的父组件从来没有被意识到标签的变化。当你有嵌套的组件时(父子关系),你需要小心翼翼地上下传递信息,它们不会自动分享自己知道的东西。