You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReactJS中能否获取MobX observable变量的引用以直接修改其值?

JavaScript 没有 C 语言那种直接操作内存地址的指针能力,也不需要通过这种方式修改 observable 值,以下是两种符合 MobX 设计逻辑的实现方案,可以做到只写一次通用逻辑,不需要为每个字段单独编写更新函数:

方案1:统一管理表单字段 + 通用更新action

把所有表单字段放到同一个 observable 对象中,仅编写一个通用的更新函数,子组件通过字段名触发更新即可,这是最常用的实现方式:

父组件改造

@observer
class Exemple extends React.Component {
  // 所有表单字段统一放在一个observable对象中管理
  @observable formData = {
    Nom: '',
    // 后续新增字段直接加在这里即可,不需要写新的更新函数
    Prenom: '',
    Age: ''
  }

  // 通用更新action,全局只需要写一次
  @action updateFormField = (fieldName, newValue) => {
    this.formData[fieldName] = newValue
  }

  render() {
    return (
      <FormComponent 
        ContainerStyle={{
          display: 'flex',
          flexDirection: 'row',
          flexWrap: 'wrap',
        }}
        ObjArray={[
          {
            InputDivStyle: { width: '49%', marginRight: '2%' },
            FieldType: 'textInput',
            FieldStyle: { borderColor: this.missingLastName ? 'red' : COLOR_NOT_BLACK },
            fieldName: 'Nom', // 绑定对应的字段名
            Placeholders: 'Ex. Durand',
            Value: this.formData.Nom,
            InputTitle: 'Nom',
          },
          // 新增字段只需要加配置项,不需要额外写更新逻辑
          {
            InputDivStyle: { width: '49%' },
            FieldType: 'textInput',
            fieldName: 'Prenom',
            Placeholders: 'Ex. Jean',
            Value: this.formData.Prenom,
            InputTitle: 'Prénom',
          }
        ]}
        onFieldChange={this.updateFormField} // 把通用更新函数传给子组件
      />
    )
  }
}

子组件改造

@observer
class FormComponent extends React.Component<props> {
  render() {
    const { ObjArray, ContainerStyle, onFieldChange } = this.props
    return (
      <div style={ContainerStyle}>
        {ObjArray.map((e, index: number) => {
          const { Disabled, FieldStyle, InputDivStyle, FieldType, Placeholders, fieldName, Value, InputTitle } = e
          return (
            <div style={InputDivStyle ?? {}} key={index + 'Input'}>
              {InputTitle && <Label medium>{InputTitle}</Label>}
              <GenericInput
                disabled={Disabled ?? false}
                placeholder={Placeholders ?? ''}
                style={FieldStyle ?? {}}
                type={FieldType ?? ''}
                value={Value ?? ''}
                onChange={evt => {
                  // 调用通用更新函数,传入字段名和新值即可
                  onFieldChange(fieldName, evt.target.value)
                }}
              />
            </div>
          )
        })}
      </div>
    )
  }
}
export default FormComponent

方案2:使用observable.box实现类“指针”效果

如果你不想把字段都整合到同一个对象中,可以用 MobX 提供的 observable.box 包装原始类型值,返回的是引用类型的observable对象,子组件拿到引用后可以直接修改值,效果和你想要的“指针”逻辑一致:

父组件改造

import { observable } from 'mobx'

@observer
class Exemple extends React.Component {
  // 用observable.box包装原始类型,返回引用类型的observable对象
  Nom = observable.box('')
  Prenom = observable.box('')

  render() {
    return (
      <FormComponent 
        ContainerStyle={{
          display: 'flex',
          flexDirection: 'row',
          flexWrap: 'wrap',
        }}
        ObjArray={[
          {
            InputDivStyle: { width: '49%', marginRight: '2%' },
            FieldType: 'textInput',
            FieldStyle: { borderColor: this.missingLastName ? 'red' : COLOR_NOT_BLACK },
            observableBox: this.Nom, // 直接传observable对象的引用
            Placeholders: 'Ex. Durand',
            Value: this.Nom.get(), // 取值用.get()方法
            InputTitle: 'Nom',
          },
          {
            InputDivStyle: { width: '49%' },
            FieldType: 'textInput',
            observableBox: this.Prenom,
            Placeholders: 'Ex. Jean',
            Value: this.Prenom.get(),
            InputTitle: 'Prénom',
          }
        ]}
      />
    )
  }
}

子组件改造

@observer
class FormComponent extends React.Component<props> {
  render() {
    const { ObjArray, ContainerStyle } = this.props
    return (
      <div style={ContainerStyle}>
        {ObjArray.map((e, index: number) => {
          const { Disabled, FieldStyle, InputDivStyle, FieldType, Placeholders, observableBox, Value, InputTitle } = e
          return (
            <div style={InputDivStyle ?? {}} key={index + 'Input'}>
              {InputTitle && <Label medium>{InputTitle}</Label>}
              <GenericInput
                disabled={Disabled ?? false}
                placeholder={Placeholders ?? ''}
                style={FieldStyle ?? {}}
                type={FieldType ?? ''}
                value={Value ?? ''}
                onChange={evt => {
                  // 直接通过引用修改observable的值,不需要额外传更新函数
                  observableBox.set(evt.target.value)
                }}
              />
            </div>
          )
        })}
      </div>
    )
  }
}
export default FormComponent

注意:JavaScript中原始类型(字符串、数字、布尔值等)都是值传递,直接把this.Nom这类原始值传给子组件时,子组件拿到的只是值的拷贝,修改拷贝不会影响父组件的原始变量,必须通过引用类型或者回调函数的方式实现跨组件的状态修改。

内容的提问来源于stack exchange,提问作者cricciardi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 06:54:00