[英]How to add image src to the state in multi step form in react
TLDR TLDR
I'm making an multiStep form for my project that is inspired from Brad Traversy's Tutorial of making Multi-Step form in React .我正在为我的项目制作一个多步骤表单,其灵感来自Brad Traversy 的在 React 中制作多步骤表单的教程。 So as per the basic structure of this form
所以按照这个表格的基本结构
I made a main Parent component called Multiform
as below我制作了一个名为
Multiform
的主要父组件,如下所示
import React, { Component } from 'react'
import StepOne from './StepOne'
export class Multiform extends Component {
state = {
step:1,
CountryFlag: 'https://raw.githubusercontent.com/MeRahulAhire/country-calling-code-html/master/phone_icon.png',
CountryCode: ''
};
handleChange = (input) => (e) => {
this.setState({ [input]: e.target.value });
};
countryFlagHandler = () =>{
this.setState({CountryFlag : this.props.state.flagImg})
}
render() {
const { CountryFlag, CountryCode } = this.state;
const values = {CountryFlag, CountryCode };
switch (step) {
case 1:
return(
<StepOne
handleChange={this.handleChange}
countryFlagHandler={this.countryFlagHandler}
values={values}
/>
)
default:
return (<h1>hello React App</h1>)
};
}
}
export default Multiform
and a child component StepOne
as below和一个子组件
StepOne
如下
import React, { Component } from 'react'
export class StepOne extends Component {
state = {
flagImg: '',
};
render() {
const { values, handleChange, countryFlagHandler } = this.props;
const selectCountryChange = () => {
const img = document.querySelector('#img');
const select = document.querySelector('#country');
img.src = `https://flagpedia.net/data/flags/h80/${select.selectedOptions[0].dataset.countrycode.toLowerCase()}.webp`;
this.setState({
flagImg: `https://flagpedia.net/data/flags/h80/${select.selectedOptions[0].dataset.countrycode.toLowerCase()}.webp`
});
countryFlagHandler()
};
return (
<div>
<div class="image" onChange={selectCountryChange}>
<img src={values.CountryFlag} id="img"/>
</div>
<select id="country" onChange={handleChange('select')} defaultValue={values.select}>
<option data-countryCode="IN" value="91">India</option>
<option data-countryCode="US" value="1">US</option>
<option data-countryCode="GB" value="44">UK</option>
</select>
</div>
)
}
}
export default StepOne
what I'm trying to do is actually to sync and persist the data of <Select/>
and <img>
in Multiform.js
Component as typically what we see in a stepper form.我要做的实际上是在
Multiform.js
组件中同步和持久化<Select/>
和<img>
的数据,就像我们在步进表单中看到的那样。
But, As in the StepOne
但是,就像在
StepOne
中一样
<img src={values.CountryFlag} id="img"/>
the img.src
is actually manipulated by the function selectCountryChange
and to keep the value of img.src
persisted I thought of creating countryFlagHandler
in Multiform
and importing it to StepOne
img.src
实际上由 function selectCountryChange
操作并保持img.src
的值保持不变我想在Multiform
中创建countryFlagHandler
并将其导入StepOne
but when i selected any value, it gave me this error:但是当我选择任何值时,它给了我这个错误:
TypeError: Cannot read property 'flagImg' of undefined TypeError:无法读取未定义的属性“flagImg”
Registration.countryFlagHandler
C:/Users/Rahul/Desktop/cfm-usersignup/src/public/form/registration.js:53
50 | this.setState({ [input]: e.target.value });
51 | };
52 | countryFlagHandler = () =>{
> 53 | this.setState({CountryFlag : this.props.state.flagImg})
| ^ 54 | }
55 |
56 |
& &
selectCountryChange
C:/Users/Rahul/Desktop/cfm-usersignup/src/public/form/credential.js:31
28 | this.setState({
29 | flagImg: `https://flagpedia.net/data/flags/h80/${select.selectedOptions[0].dataset.countrycode.toLowerCase()}.webp`
30 | });
> 31 | countryFlagHandler();
| ^ 32 | };
33 | return (
34 | <div>
Can anyone please tell me how to rectify my error?谁能告诉我如何纠正我的错误?
You can also checkout my project repo for more info. 您还可以查看我的项目存储库以获取更多信息。
As I see from your code, you try to get the flagImg propery from object that doesn't exist.正如我从您的代码中看到的,您尝试从不存在的 object 获取 flagImg 属性。 If I understood your logic correctly, you need to update the selectCountryChange and countryFlagHandler methods:
如果我正确理解了您的逻辑,则需要更新 selectCountryChange 和 countryFlagHandler 方法:
const selectCountryChange = () => {
const img = document.querySelector('#img');
const select = document.querySelector('#country');
const flagImg = `https://flagpedia.net/data/flags/h80/${select.selectedOptions[0].dataset.countrycode.toLowerCase()}.webp`;
img.src = flagImg;
this.setState({
flagImg
});
countryFlagHandler(flagImg)
};
and in the countryFlagHandler method take it from argumnets:并在 countryFlagHandler 方法中从 argumnets 中获取:
countryFlagHandler = CountryFlag =>
this.setState({ CountryFlag })
Also, your logic looks pretty dirty, maybe you could generate the flagImg property, when you select a country, set it to Multiform, and finally pass it through props to StepOne.另外,您的逻辑看起来很脏,也许您可以生成 flagImg 属性,当您 select 一个国家/地区时,将其设置为 Multiform,最后通过道具将其传递给 StepOne。
Shor answer简短的回答
You're getting an error because countryFlagHandler
is not getting the value it's expected, it doesn't have access to the StepOne
component's state.您收到错误是因为
countryFlagHandler
没有获得预期的值,它无权访问StepOne
组件的 state。 You would need to pass the value as an argument to the parent component.您需要将该值作为参数传递给父组件。
// flagImg will come as an argument from the child Component
countryFlagHandler = (flagImg) =>{
this.setState({ CountryFlag : flagImg })
}
const selectCountryChange = () => {
const img = document.querySelector('#img');
const select = document.querySelector('#country');
img.src = `https://flagpedia.net/data/flags/h80/${select.selectedOptions[0].dataset.countrycode.toLowerCase()}.webp`;
this.setState({
flagImg: `https://flagpedia.net/data/flags/h80/${select.selectedOptions[0].dataset.countrycode.toLowerCase()}.webp`
});
const countryFlag = `https://flagpedia.net/data/flags/h80/${select.selectedOptions[0].dataset.countrycode.toLowerCase()}.webp`;
// CountryFlag would be passed as an argument
countryFlagHandler(countryFlag);
};
Long Answer长答案
I would recommend refactoring your code a bit and moving all the data to the parent component rather than keeping them in two different states.我建议稍微重构您的代码并将所有数据移动到父组件,而不是将它们保持在两种不同的状态。 And also one function would be enough to handle all the data manipulation.
还有一个 function 足以处理所有数据操作。
Parent Component Multiform
父组件
Multiform
import React, { Component } from 'react'
import StepOne from './StepOne'
export class Multiform extends Component {
state = {
step: 1,
CountryFlag: 'https://raw.githubusercontent.com/MeRahulAhire/country-calling-code-html/master/phone_icon.png',
CountryCode: ''
};
handleSelectChange = (event) => {
const value = event.target.value;
const countryCode = event.target[event.target.selectedIndex].getAttribute('data-country-code');
const countryFlagImg = `https://flagpedia.net/data/flags/h80/${countryCode.toLowerCase()}.webp`;
this.setState({
select: value,
CountryFlag: countryFlagImg
});
}
render() {
const { CountryFlag, CountryCode, step } = this.state;
const values = { CountryFlag, CountryCode };
switch (step) {
case 1:
return (
<StepOne
handleChange={this.handleSelectChange}
countryFlagHandler={this.countryFlagHandler}
values={values}
/>
)
default:
return (<h1>hello React App</h1>)
};
}
}
And child Component StepOne
和子组件
StepOne
import React, { Component } from 'react'
class StepOne extends Component {
render() {
const { values, handleChange } = this.props;
return (
<div>
<div class="image">
<img src={values.CountryFlag} id="img" />
</div>
<select id="country" onChange={this.props.handleChange} defaultValue={values.select}>
<option data-country-code="IN" value="91">India</option>
<option data-country-code="US" value="1">US</option>
<option data-country-code="GB" value="44">UK</option>
</select>
</div>
)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.