Javascript ReactJS/Redux:受控输入-使用属性设置值
我使用一个受控文本字段,以监听该字段中值的变化,并在请求输入时强制输入大写或小写的值 所以我必须使用组件状态的value属性 不幸的是,如果我在另一个Redux组件中使用此组件,并且希望通过连接到Redux全局状态的属性更新此字段,我不知道如何更新 如果我使用组件的属性对受控字段进行赋值,则在对字段进行一次更改后,我将丢失链接到条目的修改(因为我不按状态的值进行赋值) 如果我在受控字段的赋值中使用状态,则根本无法检索Redux props提供的值。 有什么想法吗 我的组件的简化代码段:Javascript ReactJS/Redux:受控输入-使用属性设置值,javascript,reactjs,typescript,redux,controlled-component,Javascript,Reactjs,Typescript,Redux,Controlled Component,我使用一个受控文本字段,以监听该字段中值的变化,并在请求输入时强制输入大写或小写的值 所以我必须使用组件状态的value属性 不幸的是,如果我在另一个Redux组件中使用此组件,并且希望通过连接到Redux全局状态的属性更新此字段,我不知道如何更新 如果我使用组件的属性对受控字段进行赋值,则在对字段进行一次更改后,我将丢失链接到条目的修改(因为我不按状态的值进行赋值) 如果我在受控字段的赋值中使用状态,则根本无法检索Redux props提供的值。 有什么想法吗 我的组件的简化代码段: impo
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
发生变化时更新本地状态
我建议您添加一个propsetValue
,它将是一个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
到的更改,但我们需要小心,因为如果操作不正确,很容易创建无限循环。对不起,是我搞砸了。我不需要在输入中存储状态。当我使用状态时,我让我的字段显示在道具中的值。突然,我失去了用户输入。。。我很笨。
谢谢琳达的回答,这让我做出了反应