Это вопрос общей памяти (замыкание и контекст).
Когда вы используете экземпляр для хранения данных (и обращаетесь к нему через this
), вы не можете сохранить данные при монтировании (когда компонентперемонтируется).
Когда вы используете переменную "external", данные сохранятся.
Вот небольшой пример, просто пару раз нажмите кнопку и посмотрите, как увеличивается число внешних переменных, в то время как переменная экземпляра сбрасывается при каждом монтировании:
let externalCounter = 0;
class Test extends React.Component {
componentDidMount() {
externalCounter += 1;
this.myCounter += 1;
}
myCounter = 0;
render() {
return <div>{`external counter is ${externalCounter} and myCounter is ${
this.myCounter
}`}</div>;
}
}
class App extends React.Component {
state = { mount: true };
toggleMount = () => this.setState(({ mount }) => ({ mount: !mount }));
render() {
const { mount } = this.state;
return (
<div>
<button onClick={this.toggleMount}>toggle mount</button>
{mount && <Test />}
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root" />
Конечно, у меня сложилось впечатление, что вы используете какой-то вид экспорта модулей, и в области видимости модуля объявлена «внешняя» переменная.
Редактировать
В качестве продолжения ваших комментариев и вопросов ниже:
, поэтому два класса в отдельных файлах.Один родитель, один ребенок.Переменная уровня дочернего модуля не будет сохраняться при монтаже и монтаже.
Это не совсем так.
Учитывая этот модуль:
let externalCounter = 0;
class Test extends React.Component {
componentDidMount() {
externalCounter += 1;
this.myCounter += 1;
}
myCounter = 0;
render() {
return <div>{`external counter is ${externalCounter} and myCounter is ${
this.myCounter
}`}</div>;
}
}
export defualt Test;
Думайте об этом как о большой функции, которая имеет вложенную функцию:
function SomeModule(){
let externalCounter = 0;
function Test(props){
// some logic
}
return Test;
}
Когда вы импортируете Test
в другой модуль (файл), вы на самом деле захватываете внутреннюю функцию Test
, и она будет повторно вызываться всякий раз, когда реакции перемонтирует этот компонент, но это не означает, что SomeModule
функция будет повторно вызвана, это не будет.следовательно, externalCounter
сохранит данные при вызовах функции Test
.
Это на самом деле замыкание .