Javascript 设置“材质ui”对话框的初始状态
我有一个包含一些文本字段、下拉列表和其他内容的。每次打开或重新打开对话框时,其中一些元素需要设置为某个值。在存在某些条件(例如,加载用户数据)之前,无法加载其他元素 对于“重置”,我使用了onEnter函数。但是onEnter函数直到进入(duh!)才运行。。。但是render函数本身仍然存在,这意味着JSX中的任何逻辑或访问javascript变量都将仍然存在。这使得“onEnter”功能无法作为我设置和初始化对话框的地方 我也不能使用构造函数设置/重置此初始状态,因为在构造函数加载时(应用程序启动时),我需要构建状态的数据可能不可用。现在,我可以在渲染函数中使JSX超级复杂化,并为每个数据点设置条件。。。但对于每次应用程序更改任何内容时都会重新呈现的内容来说,这是一个很大的开销。(即使“打开”参数设置为false,“材质UI”对话框也会显示并运行整个渲染功能) 为材质ui对话框初始化值的最佳方法是什么 下面是一个超级简化的示例(在现实生活中,想象getInitialState是一个复杂得多、速度慢得多、可能是异步/网络的函数)——让我们假设用户对象在应用程序启动时不可用,实际上是在应用程序启动很久之后提取或输入的一些数据。此代码失败,因为“用户”在第一次渲染时未定义(在Onener运行之前发生) 这就行了。。。但它给了我一个运行时警告:Javascript 设置“材质ui”对话框的初始状态,javascript,reactjs,material-ui,Javascript,Reactjs,Material Ui,我有一个包含一些文本字段、下拉列表和其他内容的。每次打开或重新打开对话框时,其中一些元素需要设置为某个值。在存在某些条件(例如,加载用户数据)之前,无法加载其他元素 对于“重置”,我使用了onEnter函数。但是onEnter函数直到进入(duh!)才运行。。。但是render函数本身仍然存在,这意味着JSX中的任何逻辑或访问javascript变量都将仍然存在。这使得“onEnter”功能无法作为我设置和初始化对话框的地方 我也不能使用构造函数设置/重置此初始状态,因为在构造函数加载时(应用程
警告:无法在现有状态转换期间更新(例如在
render中)。渲染方法应该是道具和状态的纯函数。
这让我读了很多书,特别是这个问题:这让我明白我不应该忽视这个警告。此外,此方法导致返回JSX中包含的所有逻辑仍然出现。。。即使对话框未“打开”。添加一堆复杂的对话框会降低性能
当然,有一种“正确”的方法可以做到这一点。帮忙?想法?从概念上讲,您需要的是,当您刚打开对话框时,您需要重置一些项目。因此,您希望能够侦听
open
的值何时从false
更改为true
对于钩子,提供了使用usePrevious
钩子保留给定项的“旧”值的示例。然后只需使用useffect
function usePrevious(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}
function MyDialog({ dialogVisibility }) {
const prevVisibility = usePrevious(dialogVisibility);
useEffect(() => {
// If it is now open, but was previously not open
if (dialogVisibility && !prevVisibility) {
// Reset items here
}
}, [dialogVisibility, prevVisibility]);
return <Dialog open={dialogVisibility}></Dialog>;
}
您应该使用componentDidUpdate()
- 初始渲染时不调用此方法
- 当组件被更新时,利用这个机会在DOM上进行操作
- 在安装组件(插入到树中)后立即调用
- 如果需要从远程端点加载数据,这是实例化网络请求的好地方
来源:这可以通过将构造函数、getInitialState和onEnter函数保持为编写状态,并在渲染函数中添加以下三元条件来解决:
render() {
const { dialogVisibility } = this.props;
return (
<Dialog open={dialogVisibility} onEnter={this.onEnter}>
{this.state.isInitialized && dialogVisibility ?
<DialogTitle>
Hi, {this.state.user.username}
</DialogTitle> : 'Dialog Not Initialized'}
</Dialog> );
)}
render(){
const{dialogVisibility}=this.props;
返回(
{this.state.isInitialized&&dialogVisibility?
你好,{this.state.user.username}
:'对话框未初始化'}
);
)}
它实际上允许对话框适当地使用它的“onEnter”,获得正确的转换,并避免在呈现不可见时在JSX中运行任何扩展的复杂逻辑。它也不需要重构或增加编程复杂性
…但是,我承认,这感觉非常“错误”
if(!this.state.isInitialized) {
this.onEnter();
return null;
}
function usePrevious(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}
function MyDialog({ dialogVisibility }) {
const prevVisibility = usePrevious(dialogVisibility);
useEffect(() => {
// If it is now open, but was previously not open
if (dialogVisibility && !prevVisibility) {
// Reset items here
}
}, [dialogVisibility, prevVisibility]);
return <Dialog open={dialogVisibility}></Dialog>;
}
export class MyDialog extends Component {
public componentDidUpdate({ dialogVisibility : prevVisibility }) {
const { dialogVisibility } = this.props;
if (dialogVisibility && !prevVisibility) {
// Reset state here
}
}
public render() {
const { dialogVisibility } = this.props;
return <Dialog open={dialogVisibility}></Dialog>;
}
}
render() {
const { dialogVisibility } = this.props;
return (
<Dialog open={dialogVisibility} onEnter={this.onEnter}>
{this.state.isInitialized && dialogVisibility ?
<DialogTitle>
Hi, {this.state.user.username}
</DialogTitle> : 'Dialog Not Initialized'}
</Dialog> );
)}