Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/456.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript ReactJS/Redux:受控输入-使用属性设置值_Javascript_Reactjs_Typescript_Redux_Controlled Component - Fatal编程技术网

Javascript ReactJS/Redux:受控输入-使用属性设置值

Javascript ReactJS/Redux:受控输入-使用属性设置值,javascript,reactjs,typescript,redux,controlled-component,Javascript,Reactjs,Typescript,Redux,Controlled Component,我使用一个受控文本字段,以监听该字段中值的变化,并在请求输入时强制输入大写或小写的值 所以我必须使用组件状态的value属性 不幸的是,如果我在另一个Redux组件中使用此组件,并且希望通过连接到Redux全局状态的属性更新此字段,我不知道如何更新 如果我使用组件的属性对受控字段进行赋值,则在对字段进行一次更改后,我将丢失链接到条目的修改(因为我不按状态的值进行赋值) 如果我在受控字段的赋值中使用状态,则根本无法检索Redux props提供的值。 有什么想法吗 我的组件的简化代码段: impo

我使用一个受控文本字段,以监听该字段中值的变化,并在请求输入时强制输入大写或小写的值

所以我必须使用组件状态的value属性

不幸的是,如果我在另一个Redux组件中使用此组件,并且希望通过连接到Redux全局状态的属性更新此字段,我不知道如何更新

如果我使用组件的属性对受控字段进行赋值,则在对字段进行一次更改后,我将丢失链接到条目的修改(因为我不按状态的值进行赋值)

如果我在受控字段的赋值中使用状态,则根本无法检索Redux props提供的值。 有什么想法吗

我的组件的简化代码段:

import { TextField } from '@material-ui/core';
import React from 'react';
import { 
  MyInputProperties, 
  defaultInputFieldPropsValue
} from './MyInputProperties';
import { MyInputState } from './MyInputState';

export class MyInput
  extends React.Component<MyInputProperties, MyInputState> {

  static readonly VERSION: number = 100;

  public static defaultProps = defaultInputFieldPropsValue;

  constructor(props: MyInputProperties) {
    super(props);
    this.state = {
      ...this.state,
      value: this.props.value
    };
  }

  protected render(): JSX.Element {
    const {
      error,
      focused,
      helperText,
      label,
      required,
      type,
      textTransform,
      style,
      value: propValue
    } = this.props;

    const { value: stateValue } = this.state;

    const element = (
      <TextField
        inputProps={{ style: { textTransform: textTransform } }}
        id={this.id}
        disabled={this.isDisabled}
        error={error}
        focused={focused}
        helperText={helperText}
        label={label}
        onChange={this.handleChange.bind(this)}
        required={required}
        style={style}
        type={type}
        defaultValue={propValue}
        value={stateValue}
      />
    );

    return element;
  }

  private formatValue(value?: string): string | undefined {
    const { textTransform } = this.props;
    let curValue = value;
    if (curValue && textTransform) {
      if (textTransform === 'uppercase') {
        curValue = curValue.toUpperCase();
      } else if (textTransform === 'lowercase') {
        curValue = curValue.toLowerCase();
      }
    }
    return curValue;
  }

  /**
   * Callback fired when changing the value.
   * @param event Change event
   */
  private handleChange(event: React.ChangeEvent<HTMLInputElement>): void {
    const value = event.target.value;
    this.setState({ value: this.formatValue(value) });
  }
}
从'@material ui/core'导入{TextField};
从“React”导入React;
导入{
MyInputProperties,
defaultInputFieldPropsValue
}来自“/MyInputProperties”;
从“./MyInputState”导入{MyInputState};
导出类MyInput
扩展React.Component{
静态只读版本:编号=100;
公共静态defaultProps=defaultInputFieldPropsValue;
构造函数(props:MyInputProperties){
超级(道具);
此.state={
…这个州,
值:this.props.value
};
}
受保护的呈现():JSX.Element{
常数{
错误,
专注的,
帮助文字,
标签,
必修的,
类型,
文本转换,
风格
值:propValue
}=这是道具;
const{value:stateValue}=this.state;
常量元素=(
);
返回元素;
}
私有格式值(值?:字符串):字符串|未定义{
const{textTransform}=this.props;
让曲线值=值;
if(曲线值和文本转换){
if(textTransform===‘大写’){
curValue=curValue.toUpperCase();
}else if(textTransform==='lowercase'){
curValue=curValue.toLowerCase();
}
}
返回曲线值;
}
/**
*更改值时触发回调。
*@param事件更改事件
*/
私有handleChange(事件:React.ChangeEvent):void{
常量值=event.target.value;
this.setState({value:this.formatValue(value)});
}
}

您希望组件通过道具获取并更改其值,而不是将值存储在本地状态。这样,组件就不需要知道或关心该值是来自redux还是来自另一个组件的状态

如果愿意,您可以保留一个本地状态,但您希望
props.value
成为唯一的真相来源,并在
props.value
发生变化时更新本地状态

我建议您添加一个prop
setValue
,它将是一个
void
函数,接受一个
字符串。当
TextField
更改时,我们将对新值应用正确的格式,然后使用新的格式值调用
setValue

关于代码的一些旁注:

  • 您可以使用spread操作符一次将大量道具传递给
    TextField
    ,而不是单独分配
  • 不应将元素分配给
    常量元素
    。直接退就行了
这里有一个简单的函数组件版本。此组件获取
TextField
的所有有效道具并将其传递给用户。我们在输入的每次更改上强制使用大小写,但请注意,我们不检查初始值的大小写,也不检查它是否由于外部原因而更改

import React from "react";
import { TextField, TextFieldProps } from '@material-ui/core';

type MyInputProperties = TextFieldProps & {
  textTransform?: "uppercase" | "lowercase";
  setValue(value: string): void;
  value?: string;
}

export const CaseEnforcingInput = ({value = '', setValue, textTransform, ...props}: MyInputProperties) => {

  const formatValue = (value?: string): string | undefined => {
    let curValue = value;
    if (curValue && textTransform) {
      if (textTransform === 'uppercase') {
        curValue = curValue.toUpperCase();
      } else if (textTransform === 'lowercase') {
        curValue = curValue.toLowerCase();
      }
    }
    return curValue;
  }

  const handleChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
    const value = event.target.value;
    setValue( formatValue(value) );
  }
  
  return (
    <TextField
      {...props} // pass though all other props
      onChange={handleChange}
      value={value}
      //inputProps={{ style: { textTransform: textTransform } }}
  />
  )
};
从“React”导入React;
从“@material ui/core”导入{TextField,TextFieldProps};
键入MyInputProperties=TextFieldProps&{
textTransform?:“大写”|“小写”;
setValue(值:字符串):void;
值?:字符串;
}
export const CaseEnforcingInput=({value='',setValue,textTransform,…props}:MyInputProperties)=>{
常量formatValue=(值?:字符串):字符串|未定义=>{
让曲线值=值;
if(曲线值和文本转换){
if(textTransform===‘大写’){
curValue=curValue.toUpperCase();
}else if(textTransform==='lowercase'){
curValue=curValue.toLowerCase();
}
}
返回曲线值;
}
常量handleChange=(事件:React.ChangeEvent):void=>{
常量值=event.target.value;
setValue(formatValue(value));
}
返回(
)
};

如果
props.value
与格式不匹配,我们可以使用
componentDidMount
/
useffect
调用格式正确的
setValue
。我们还想检查
props.textTransform
何时更改。我们可以检查
props.value
到的更改,但我们需要小心,因为如果操作不正确,很容易创建无限循环。

对不起,是我搞砸了。我不需要在输入中存储状态。当我使用状态时,我让我的字段显示在道具中的值。突然,我失去了用户输入。。。我很笨。 谢谢琳达的回答,这让我做出了反应