React JS跨不同文件组件设置输入框readOnly属性方法
跨独立JS文件实现组件联动方案
完全可以实现需求,核心是打通两个独立组件之间的状态同步通道,以下是三种通用实现思路,适配不同技术栈场景:
方案1:共同父组件传参(推荐React/Vue等框架场景使用)
从你贴的代码(this.state、TextField/Button组件)判断你大概率在用React类组件开发,这种场景下最规范的实现是把公共状态提升到两个组件共同的父组件中维护:
- 父组件统一管理输入框值、只读标记、按钮禁用状态三个核心变量
- 把状态和修改状态的回调函数通过props分别传给两个子组件
- 输入框组件接收只读状态控制自身属性,按钮组件接收点击回调触发状态修改
代码改造示例
- 父组件(同时引入两个JS文件的组件)
// App.js import React from 'react'; import TextFieldComp from './one.js'; import ConfirmButton from './second.js'; class App extends React.Component { constructor(props) { super(props); this.state = { jobsValue: '', isInputReadonly: false, valid: false, isBtnDisabled: false } } handleInputChange = (e) => { const val = e.target.value.trim(); this.setState({ jobsValue: e.target.value, valid: !!val }) } handleConfirmClick = () => { this.setState({ isInputReadonly: true, isBtnDisabled: true }) } render() { return ( <div> <TextFieldComp value={this.state.jobsValue} readOnly={this.state.isInputReadonly} onInputChange={this.handleInputChange} /> <ConfirmButton valid={this.state.valid} isDisabled={this.state.isBtnDisabled} onConfirm={this.handleConfirmClick} /> </div> ) } } export default App;
- 改造one.js的输入框组件
// one.js import { TextField } from '@mui/material'; // 对应你用的组件库引入即可 const TextFieldComp = (props) => { return <TextField type="text" name={'jobs'} value={props.value} fullWidth InputProps={{ readOnly: props.readOnly }} onChange={props.onInputChange} /> } export default TextFieldComp;
- 改造second.js的按钮组件
// second.js import { Button } from '@mui/material'; // 对应你用的组件库引入即可 const ConfirmButton = (props) => { return <Button variant="contained" disabled={!props.valid || props.isDisabled} onClick={props.onConfirm} > Confirm </Button> } export default ConfirmButton;
方案2:全局状态共享(适配组件层级跨度大的场景)
如果两个组件在页面中嵌套层级差很大,层层传props太繁琐,可以把公共状态放到全局作用域:
- 框架场景可以用Redux/Context(React)、Pinia/Vuex(Vue)这类官方状态管理工具
- 原生JS场景可以直接把状态挂载到
window对象上,两个JS文件都能读写 - 输入框组件监听全局状态变化,自动切换只读属性;按钮点击时直接修改全局状态值
原生JS极简实现示例:
// 公共全局状态,两个JS文件都能访问 window.commonState = { isJobsInputReadonly: false }
// one.js 逻辑 const jobsInput = document.querySelector('input[name="jobs"]'); // 监听状态变化更新输入框属性 setInterval(() => { jobsInput.readOnly = window.commonState.isJobsInputReadonly; }, 50)
// second.js 逻辑 const confirmBtn = document.querySelector('button'); confirmBtn.addEventListener('click', () => { window.commonState.isJobsInputReadonly = true; confirmBtn.disabled = true; })
方案3:自定义事件通信(适配无框架原生场景)
不想污染全局命名空间的话,可以直接用浏览器自带的自定义事件能力通信,两个组件不需要互相引用:
- 输入框组件在
document上监听自定义的确认事件,收到事件后把自身设为只读 - 按钮组件点击时,在
document上派发对应的自定义事件即可
代码示例:
// one.js 逻辑 const jobsInput = document.querySelector('input[name="jobs"]'); document.addEventListener('jobsConfirm', () => { jobsInput.readOnly = true; })
// second.js 逻辑 const confirmBtn = document.querySelector('button'); confirmBtn.addEventListener('click', () => { document.dispatchEvent(new CustomEvent('jobsConfirm')); confirmBtn.disabled = true; })
注意:用框架开发时优先选择方案1,尽量避免直接手动操作DOM,防止和框架自身的渲染逻辑冲突。
内容的提问来源于stack exchange,提问作者Bekka
相关产品推荐
相关产品推荐

