javascript - React子组件不获取 Prop 并更新状态

标签 javascript reactjs

我有一个使用带有输入字段的子组件的表单。我已经使用 props 从父组件获取数据,但它没有将 prop 值添加到输入字段。控制台中没有错误。

父组件:

const {
  address,
  errors
} = this.state;

return (
    <form noValidate autoComplete="off" onSubmit={this.onSubmit.bind(this)}>
     <LocationInputGroup
        errors={errors}
        address={address}
     />

     <Button
        type="submit"
        style={{ marginRight: 10, marginTop: 20 }}
        variant="callToAction"
    > Submit</Button>
    </form>
);

子组件:

constructor(props) {
  super(props);

  this.state = {
     address: "",
     errors: {}
  };
}

componentDidMount() {
        this.setState({
            errors: this.props.errors,
            address: this.props.address
        });
}

render() {
  const {
    address,
    errors
  } = this.state;
  return (
    <div>
      <InputGroup
        value={address}
        error={errors.address}
        label="Address"
        name={"address"}
        onChange={e => this.setState({ address: e.target.value })}
        placeholder={"Address"}
      />
    </div>
  );
}

InputGroup 组件:

class InputGroup extends Component {
    constructor(props) {
        super(props);
    }

    //TODO check if scrolling still changes with number inputs
    //Bug was in Chrome 73 https://www.chromestatus.com/features/6662647093133312
    //If it's no longer a bug these listeners can be removed and the component changed back to a stateless component
    handleWheel = e => e.preventDefault();

    componentDidMount() {
        if (this.props.type === "number") {
            ReactDOM.findDOMNode(this).addEventListener("wheel", this.handleWheel);
        }
    }

    componentWillUnmount() {
        if (this.props.type === "number") {
            ReactDOM.findDOMNode(this).removeEventListener("wheel", this.handleWheel);
        }
    }

    render() {
        const {
            disabled,
            classes,
            error,
            value,
            name,
            label,
            placeholder,
            type,
            isSearch,
            onChange,
            onBlur,
            onFocus,
            multiline,
            autoFocus,
            InputProps = {},
            autoComplete,
            allowNegative,
            labelProps
        } = this.props;

        if (type === "phone") {
            InputProps.inputComponent = PhoneNumberInputMask;
        }

        let onChangeEvent = onChange;
        //Stop them from entering negative numbers unless they explicitly allow them
        if (type === "number" && !allowNegative) {
            onChangeEvent = e => {
                const numberString = e.target.value;
                if (!isNaN(numberString) && Number(numberString) >= 0) {
                    onChange(e);
                }
            };
        }

        return (
            <FormControl
                className={classes.formControl}
                error
                aria-describedby={`%${name}-error-text`}
            >
                <FormatInputLabel {...labelProps}>{label}</FormatInputLabel>
                <TextField
                    error={!!error}
                    id={name}
                    type={type}
                    value={value}
                    onChange={onChangeEvent}
                    margin="normal"
                    onBlur={onBlur}
                    onFocus={onFocus}
                    InputProps={{
                        ...InputProps,
                        classes: {
                            input: classnames({
                                [classes.input]: true,
                                [classes.searchInput]: isSearch
                            })
                        }
                    }}
                    placeholder={placeholder}
                    multiline={multiline}
                    autoFocus={autoFocus}
                    disabled={disabled}
                    autoComplete={autoComplete}
                    onWheel={e => e.preventDefault()}
                />

                <FormHelperText
                    className={classes.errorHelperText}
                    id={`${name}-error-text`}
                >
                    {error}
                </FormHelperText>
            </FormControl>
        );
    }
}

InputGroup.defaultProps = {
    value: "",
    type: "text",
    labelProps: {}
};

InputGroup.propTypes = {
    error: PropTypes.string,
    value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
    name: PropTypes.string.isRequired,
    label: PropTypes.string,
    placeholder: PropTypes.string,
    type: PropTypes.string,
    isSearch: PropTypes.bool,
    onChange: PropTypes.func.isRequired,
    onBlur: PropTypes.func,
    onFocus: PropTypes.func,
    multiline: PropTypes.bool,
    autoFocus: PropTypes.bool,
    InputProps: PropTypes.object,
    disabled: PropTypes.bool,
    autoComplete: PropTypes.string,
    allowNegative: PropTypes.bool,
    labelProps: PropTypes.object
};

export default withStyles(styles)(InputGroup);

我希望有人能够建议问题是什么以及如何克服它。

最佳答案

通常当我们从父级传递数据时,我们认为它是不可变(即) 不应直接从子组件更改

因此,我们可以做的是直接使用父级的 prop 值并使用方法从父级进行变异或更改

下面的代码是不言自明的。

父级

class Parent {

  // parent immutable state
  public parentObject: object = {
     location: "",
     phoneNo: ""
  };

  constructor() {
    this.state = {
       parentObject: this.parentObject
    }
  }


  public onParentObjectChangeCallBack(key: string, value: string | number) {
    this.state.parentObject[key] = value;
    // to rerender
    this.setState();
  }

  public render () {
    return <ChildComponent parentObject={this.state.parentObject} 
           onChange={this.onParentObjectChangeCallBack} />
  }

}

child

class ChildComponent {
  @Prop
  public parentObject: object;

  @Prop
  public onChange: Function;

  public render() {
     <div>
        {
          this.parentObject.keys.map((key) => {
            return <div>
                     <span> {{key}}</span>
                     // calls parent method to change the immutable object
                     <input value={{this.parentObject[key]}} onChange=(val) => 
                            this.onChange(key, val) />
                   </div>
          })
        }
     </div>


  }
}

关于javascript - React子组件不获取 Prop 并更新状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59155828/

相关文章:

javascript - 如何将对象加载到 jQuery 对象

javascript - 使用 jquery onclick 和 mouseup 事件检测长按时如何修复多次执行

javascript - 无法绑定(bind)到 'pdfTitle',因为它不是 'app-pdf-viewer' 的已知属性

javascript - 在 PDF 文件上打印生成的 QR 码

reactjs - 使用React Hooks多次获取数据axios

javascript - 扩展 Highmaps 副作用

javascript - 跨域请求

javascript - 如何在 useEffect/useCallback-hook 中正确处理来自 React Context 的数据

reactjs - 如何让 Three.js 在 React Native 中运行(没有 WebView)?

reactjs - React 中 MQTT 协议(protocol)的使用