TLDR
我正在为我的项目做一个受布拉德·特拉弗西的“多步反应”教程启发的布拉德·特拉弗西的“多步反应”教程表单。所以根据这个表格的基本结构

我制作了一个名为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和一个子组件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实际上,我要做的是在<Select/>组件中同步和持久化<img>和Multiform.js组件中的数据,就像我们在分步器中看到的那样。
但是,就像在StepOne
<img src={values.CountryFlag} id="img"/>img.src实际上是由selectCountryChange函数操作的,为了使img.src的值保持不变,我想在Multiform中创建countryFlagHandler并将其导入StepOne
但是当我选择任何值时,它给了我一个错误:
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>有人能告诉我如何纠正我的错误吗?
发布于 2020-05-14 17:08:51
Shor应答
您将得到一个错误,因为countryFlagHandler没有得到它所期望的值,它无法访问StepOne组件的状态。您需要将该值作为参数传递给父组件。
  // 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);
   };长答案
我建议重构代码并将所有数据移动到父组件,而不是将它们保持在两种不同的状态。还有一个函数就足以处理所有的数据操作。
父组件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>)
    };
  }
}和子组件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>
    )
  }
}发布于 2020-05-14 17:03:06
正如我从您的代码中看到的,您尝试从不存在的对象获取flagImg属性。如果我正确理解了您的逻辑,您需要更新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)
};在countryFlagHandler方法中,从argumnet获取它:
countryFlagHandler = CountryFlag =>
    this.setState({ CountryFlag })而且,您的逻辑看起来很脏,也许您可以生成flagImg属性,当您选择一个国家,将其设置为多形性,并最终通过道具传递给StepOne。
https://stackoverflow.com/questions/61727371
复制相似问题