如何在react中以多步形式将图片src添加到状态中?

问题描述 投票:0回答:2

TLDR 我正在为我的项目制作一个多步骤表格,它的灵感来自于 Brad Traversy的React多步骤表单制作教程.因此,按照这种形式的基本结构 enter image description here 我做了一个名为 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 执拗的我想到了创造 countryFlagHandlerMultiform 并将其导入到 StepOne

但当我选择任何值时,它给了我这个错误。

TypeError.Canot read property 'flagImg' of undefined: 无法读取未定义的属性'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>

谁能告诉我如何纠正我的错误?

你也可以查看我的项目回帖了解更多信息。

reactjs default-value react-props setstate react-state-management
2个回答
0
投票

简答

你得到一个错误,因为 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>
    )
  }
}

运行示例


0
投票

我从你的代码中看到,你试图从不存在的对象中获取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方法中从argumnets中获取。

countryFlagHandler = CountryFlag =>
    this.setState({ CountryFlag })

还有,你的逻辑看起来很脏,也许你可以生成flagImg属性,当你选择一个国家时,把它设置为多格式,最后通过道具传递给StepOne.

© www.soinside.com 2019 - 2024. All rights reserved.