是否可以在React应用程序外部更改组件状态?

时间:2020-05-02 16:06:17

标签: reactjs react-hooks

对于一个简单的React应用程序:

// App.js
import React, { useState } from 'react';

const App = () => {
  const [name, setName] = useState('hello'); // state
  return <div>{name}</div>;
};
export default App;

// main.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));

window.changeNameTo = ? // a method

然后在控制台中,我可以运行changeNameTo('world')来更改状态(不仅是html或DOM),这可能吗?

更新

实际上,我在同一页面的不同div上安装了两个React应用程序(旧版,也不小),因此有一个要求,即单击一个应用程序中的按钮可以触发另一个应用程序的更改。由于不值得将其重构和整合以满足很小的需求,因此黑客解决方案是可以接受的并且是首选。从我的角度来看,我将编写一个委托客户端(也许使用window作为中间位置)。

3 个答案:

答案 0 :(得分:0)

从技术上讲您可以,但是在做这种事情时应该非常小心。 在这里看看一个例子:

https://codesandbox.io/s/sweet-gareth-9owzq?file=/src/index.js

尝试使用控制台并调用ChangeName("[YourWantedStr]");

请明确-您的问题是是否可能。 是的。 但是,如果您需要以某种方式来改变状态,那么您可能在构建应用程序时就使用了糟糕的体系结构。

答案 1 :(得分:0)

仅用于调试-当您需要组件外部的功能时,可以将其包装在箭头功能中并console.log()。然后,在Chrome中,您可以右键单击控制台上的功能,然后选择“存储为全局变量”,该名称将另存为tempX(如果是第1个,则保存为1)。现在,您可以从控制台使用它。

这比向window对象添加功能要好,因为在为生产而构建时,lint会警告您console.log()

在摘要中,您必须首先选择正确的iframe(在Chrome浏览器中单击top)。

const { useState } = React;

const App = () => {
  const [name, setName] = useState('hello'); // state
  
  console.log((...args) => setName(...args));
  
  return <div>{name}</div>;
};

ReactDOM.render(<App />, document.getElementById('root'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

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

答案 2 :(得分:0)

我没有对此进行测试,但是我认为您可以将setName函数分配给窗口对象的属性。并在代码中的任何地方以window.setName的身份调用