Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 设置“材质ui”对话框的初始状态_Javascript_Reactjs_Material Ui - Fatal编程技术网

Javascript 设置“材质ui”对话框的初始状态

Javascript 设置“材质ui”对话框的初始状态,javascript,reactjs,material-ui,Javascript,Reactjs,Material Ui,我有一个包含一些文本字段、下拉列表和其他内容的。每次打开或重新打开对话框时,其中一些元素需要设置为某个值。在存在某些条件(例如,加载用户数据)之前,无法加载其他元素 对于“重置”,我使用了onEnter函数。但是onEnter函数直到进入(duh!)才运行。。。但是render函数本身仍然存在,这意味着JSX中的任何逻辑或访问javascript变量都将仍然存在。这使得“onEnter”功能无法作为我设置和初始化对话框的地方 我也不能使用构造函数设置/重置此初始状态,因为在构造函数加载时(应用程

我有一个包含一些文本字段、下拉列表和其他内容的。每次打开或重新打开对话框时,其中一些元素需要设置为某个值。在存在某些条件(例如,加载用户数据)之前,无法加载其他元素

对于“重置”,我使用了onEnter函数。但是onEnter函数直到进入(duh!)才运行。。。但是render函数本身仍然存在,这意味着JSX中的任何逻辑或访问javascript变量都将仍然存在。这使得“onEnter”功能无法作为我设置和初始化对话框的地方

我也不能使用构造函数设置/重置此初始状态,因为在构造函数加载时(应用程序启动时),我需要构建状态的数据可能不可用。现在,我可以在渲染函数中使JSX超级复杂化,并为每个数据点设置条件。。。但对于每次应用程序更改任何内容时都会重新呈现的内容来说,这是一个很大的开销。(即使“打开”参数设置为false,“材质UI”对话框也会显示并运行整个渲染功能)

为材质ui对话框初始化值的最佳方法是什么

下面是一个超级简化的示例(在现实生活中,想象getInitialState是一个复杂得多、速度慢得多、可能是异步/网络的函数)——让我们假设用户对象在应用程序启动时不可用,实际上是在应用程序启动很久之后提取或输入的一些数据。此代码失败,因为“用户”在第一次渲染时未定义(在Onener运行之前发生)

这就行了。。。但它给了我一个运行时警告:
警告:无法在现有状态转换期间更新(例如在
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上进行操作
如果需要在打开对话框之前预加载数据,可以使用componentDidMount()

  • 在安装组件(插入到树中)后立即调用
  • 如果需要从远程端点加载数据,这是实例化网络请求的好地方
React家伙添加了useEffect钩子,这与您描述的情况完全一样,但是您需要重构到一个功能组件。
来源:

这可以通过将构造函数、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> );
)}