我在我的Reaction应用程序中创建了一个更新页面.

总而言之,当我单击某个div时,它会在输入字段中显示数据.例如,当我单击第一个字段,在那里输入一些内容,然后单击另一个div时,我所做的更改就会消失.我希望如果我在其中进行更改,它应该在保存之前保留在那里.我怎么能做到这一点?

<div className="detailsPage-panel-right">
                  {
                    this.state.activeFields?.fields?.map(field => {
                      const config = this.config.fields.find(fieldConfig =>
                        fieldConfig.key === field.key)
                      const inputConfig = {
                        type: config?.dataType.type,
                        id: config?.key,
                        label: config?.displayName,
                        required: false,
                        autofocus: false,
                        value: field.value
                      };
                      const inputBindings: ITextInputBindings = {}
                      return (
                        <div key={`${this.state.activeFields.key}-${field.key}`}>
                          <TextInput config={inputConfig} bindings={inputBindings}></TextInput>
                        </div>
                      )
                    })
                  }
</div>

Text input component

import "./text-field.scss";
import { Form } from "react-bootstrap";
import { Component } from "../../utils/stateless-component";

export interface ITextInputBindings {
}

export interface ITextInputConfig {
  type: "text" | "dateTime" | "enumeration" | "guid" | undefined,
  id: string | undefined,
  label: string | undefined,
  placeholder?: string,
  required: boolean,
  autofocus?: boolean,
  value?: string
}

class TextInput extends Component<ITextInputConfig,ITextInputBindings> {
  render() {
    return (
      <div className="textInput">
        <Form.Group className="mb-3 textInput-group">
          <Form.Label htmlFor={this.config.id}>{this.config.label}</Form.Label>
          <Form.Control type={this.config.type}
            placeholder={this.config.placeholder}
            required={this.config.required}
            id={this.config.id}
            autoFocus={this.config.autofocus}
            defaultValue={this.config.value} />
        </Form.Group>

      </div>
    );
  }
}

export default TextInput; 

我想我应该使用onChange方法,但我不知道如何使用.

推荐答案

key prop

Remember to check re-render when your activeFields.field changes, because you had set the key in your TextInput.
This will result in the TextInput component be unmount and create a new one

       // ???? check this state. Do not mutate to prevent re-render 
       this.state.activeFields?.fields?.map(field => {
                      const config = this.config.fields.find(fieldConfig =>
                        fieldConfig.key === field.key)
                      const inputConfig = {
                        type: config?.dataType.type,
                        id: config?.key,
                        label: config?.displayName,
                        required: false,
                        autofocus: false,
                        value: field.value
                      };
                      const inputBindings: ITextInputBindings = {}
                      return (
                        // ???? if key be mutated from state, it will create a new component intead of old one
                        <div key={`${this.state.activeFields.key}-${field.key}`}>
                          <TextInput config={inputConfig} bindings={inputBindings}></TextInput>
                        </div>
                      )
                    })

保存输入值

如果您想要以TextInput为单位保存输入值,这取决于您希望按状态保存输入值的组件.

Save in the child component (In your case the TextInput)

TextInput 组件中添加一个onChange事件和一个状态

然后加props,因为你给了它props .

就像这个由您的代码编辑的示例(可能无法运行,但概念应该可以运行)

class TextInput extends Component<ITextInputConfig,ITextInputBindings> {
  constructor(props) {
    super(props);
    this.state = { ...this.props }
  }

  // set state 
  const handleChange = (e) => {
    this.setState({...this.state, 
    config: { ...this.state.config, value: e.target.value } 
    })
  }

  render() {
     return (
      <div className="textInput">
        <Form.Group className="mb-3 textInput-group">
          <Form.Label htmlFor={this.config.id}>{this.config.label}</Form.Label>
          <Form.Control type={this.config.type}
            placeholder={this.config.placeholder}
            required={this.config.required}
            id={this.config.id}
            autoFocus={this.config.autofocus}
            defaultValue={this.config.value}
            // ???? add onChange event on Form.Control
            onChange={handleChange}
             />
        </Form.Group>
      </div>
    );
  }
}

Save in parent component

And if you need control or save state changes from parent component
add a state and a changeState function in your parent component, and give changeState to TextInput's props and let the changeState prop mutate parent's value in child's input onChange event

示例:

class ParentComponent extends React.Component {
   constructor(props) {
    super(props);
    this.state = { inputValue: undefined }
  }

  const handleChange = (e) =>{
    if(e.target)
      this.setState({...this.state, inputValue: e.target.value});
  }

  render(){
    return (
      <div className="detailsPage-panel-right">
                  {
                    this.state.activeFields?.fields?.map(field => {
                      const config = 
                        this.config.fields.find(fieldConfig =>
                        fieldConfig.key === field.key)
                        const inputConfig = {
                        type: config?.dataType.type,
                        id: config?.key,
                        label: config?.displayName,
                        required: false,
                        autofocus: false,
                        value: field.value
                        };
                        const inputBindings: ITextInputBindings = {}
                        return (
                        <div key= 
                       {`${this.state.activeFields.key}-${field.key}`}
                        >
                        <TextInput 
                        config={inputConfig} 
                        bindings={inputBindings}
                        onChange={handleChange}>
                        </TextInput>
                        </div>
                      )
                    })
                  }
         </div>
    )
  }  
}

// TextInput
class TextInput extends Component<ITextInputConfig,ITextInputBindings> {
 constructor(props) {
    super(props);
    this.state = { ...this.props }
  }

  const handleChange = (e) => {
    this.props.onChange(e);
  }

  render() {
    return (
      <div className="textInput">
        <Form.Group className="mb-3 textInput-group">
          <Form.Label htmlFor={this.config.id}>{this.config.label} </Form.Label>
          <Form.Control 
            type={this.config.type}
            placeholder={this.config.placeholder}
            required={this.config.required}
            id={this.config.id}
            autoFocus={this.config.autofocus}
            defaultValue={this.config.value} 
            onChange={handleChange}/>
        </Form.Group>

      </div>
    );
  }
}
Code snippet example

一个示例,说明了子项如何改变父项的值,以及当键更改时组件如何销毁.(由functional component人 compose )

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

    <div id="root"></div>

    <script type="text/babel">
      function App () {
        const [keys, setKeys] = React.useState([1, 2]);
        const [inputValue, setInputValue] = React.useState(``);
        const [inputValue2, setInputValue2] = React.useState(``);

        const handleKeys = () =>{
          let temp = [...keys];
          temp[0] = temp[0] + 2;
          temp[1] = temp[1] + 2;
          setKeys([...temp])
        }

        return <div>
          <div><button>Click this still remain the changes you had made</button></div>
          <div><button onClick={handleKeys}>Click this to change keys, and will refresh the 'Number' prefix input component</button></div>
          <br />
          {
            keys.map((key)=>{ 
                if (key % 2 === 0) {
                  return <div key={key}>Number {key}: <Child setInputValue={setInputValue2}></Child></div> 
                }
                else {
                  return <div key={key}>Number {key}: <Child setInputValue={setInputValue}></Child></div>  
                }
              })
          }
          
          <br />
          <div>child components that do not have key</div>
          <div>First Child's Input: <Child setInputValue={setInputValue}></Child></div>
          <div>Second Child's Input: <Child setInputValue={setInputValue2}></Child></div>
          <br />
          <div>inputValue(in parent from first child): {inputValue}</div>
          <div>inputValue2(in parent from second child): {inputValue2}</div>
        </div>
      }
      
      function Child ({ setInputValue }) {
        const handleChange = (e) => {
          if(setInputValue)
            setInputValue(e.target.value);
        }
      
      return <input onChange={handleChange}></input>
      }
    </script>

    <script type="text/babel">
        ReactDOM.render(
            <App></App>
            , document.getElementById("root"));
    </script>

Dynamically mutate and save input value by state

I guess you need save value dynamically by this.state.activeFields?.fields.
Create a state object for recording your active input value. And add a handleChange function which can change value by e.target.id

// In your TextInput's parent
 constructor(props) {
    super(props);
    this.state = { inputValues: {} }
  }

const handleChange = (e)=>{
  const changeField = this.state.activeFields?.fields.find(x=>x.key === e.target.key);
  if(changeField) {
    this.setState({...this.state.inputValues, changeField.key: e.target.value})
  }
}

this.state.activeFields?.fields?.map( (field) => {
return (
<TextInput 
  config={inputConfig} 
  bindings={inputBindings}
  // add onChange event
  onChange={handleChange}
>
</TextInput>
)
})
more refernece:

Lifting State Up


其他

根据react-bootstrap's Form.Control API doc,应该使用defaultValuevalue的整数

Javascript相关问答推荐

Phaser框架-将子对象附加到Actor

将状态向下传递给映射的子元素

Rehype将hashtag呈现为URL

你怎么看啦啦队的回应?

如何在coCos2d-x中更正此错误

使用Google API无法进行Web抓取

类构造函数忽略Reaction Native中的可选字段,但在浏览器中按预期工作

在画布中调整边上反弹框的大小失败

如何用javascript更改元素的宽度和高度?

为列表中的项目设置动画

如何更改Html元素S的 colored颜色 ,然后将其褪色为原始 colored颜色

如何在AG-Grid文本字段中创建占位符

如何在Highlihte.js代码区旁边添加行号?

如何检测当前是否没有按下键盘上的键?

将字体样式应用于material -UI条形图图例

Firefox的绝对定位没有达到预期效果

我如何才能让p5.js在不使用实例模式的情况下工作?

Html/JS:如何在脚本执行前阻止呈现?

将数据添加到数据库时不输出

FiRestore按字段的提取顺序