反应变量在外部事件中不反应
React variable not reactive in external event
我是一名 Vue 开发人员,正在尝试开发 React 应用程序。
我正在尝试将 CodeMirror 包装在 React 应用程序中,但我 运行 遇到了一些麻烦。不确定如何修复它。
我正在实例化一个 CodeMirror 编辑器并将一些事件处理程序附加到它。
这些处理程序是这样的:
当您聚焦编辑器时,isFocused
变量变为 true
。
当您将焦点移出编辑器时,isFocused
变量变为 false
。
当您在编辑器中输入时,如果 isFocused
变量为真,您应该执行一些操作。
在最后一个处理程序中,我需要访问一个 reactive 变量集 useState
(isFocused
)。
该变量在该函数的上下文中不是反应性的。它被读取为默认值 false
.
组件看起来像这样:
import React, {useState, useEffect, useRef} from 'react';
import 'codemirror/lib/codemirror.css'
import 'codemirror/mode/javascript/javascript'
import CodeMirror from 'codemirror'
import './App.css';
function App() {
const textArea = useRef()
const [isFocused, setIsFocused] = useState(false)
const [data, setData] = useState('sample data')
const handleChange = () => {
console.log('isFocused->', isFocused);
if (isFocused) {
// do something here
}
}
const handleEditorFocus = () => {
setIsFocused(true)
}
const handleEditorBlur = () => {
setIsFocused(false)
}
useEffect(() => {
const editor = CodeMirror.fromTextArea(textArea.current)
editor.on('change', handleChange)
editor.on('focus', handleEditorFocus)
editor.on('blur', handleEditorBlur)
return () => {
editor.toTextArea()
}
}, []);
return (
<div>
{isFocused ? 'focused' : 'not focused'}
<textarea
ref={textArea}
value={data}
onChange={(e) => setData(e.target.value)}
></textarea>
</div>
)
};
export default App;
请指出这个问题的正确方向。
谢谢!
更新:
我什至做了一个 repl.it here.
更新 2
stackblitz 上更好的演示。
我基本上需要访问 handleChange
函数中的 instance
和 change
参数。
添加一个带有回调的 useEffect
函数到 handleChange
并将其作为参数传递 isFocused
。
PS: 不要忘记 Boolean()
显示 isFocused 的状态,否则它 returns 一个对象。
(参见页面底部的演示 link)
import React, { useState, useEffect, useRef } from 'react';
import 'codemirror/lib/codemirror.css';
import 'codemirror/mode/javascript/javascript';
import CodeMirror from 'codemirror';
export default function App() {
const textArea = useRef();
const [isFocused, setIsFocused] = useState(false);
const [data, setData] = useState('sample data');
const handleChange = isF => {
console.log('isFocused->', Boolean(isF)); // here
if (isFocused) {
// ...
}
};
const handleEditorFocus = () => {
setIsFocused(true);
};
const handleEditorBlur = () => {
setIsFocused(false);
};
useEffect(() => { // here
handleChange(isFocused);
}, [isFocused]);
useEffect(() => {
const editor = CodeMirror.fromTextArea(textArea.current);
editor.on('change', handleChange);
editor.on('focus', handleEditorFocus);
editor.on('blur', handleEditorBlur);
return () => {
editor.toTextArea();
};
}, []);
return (
<div>
{isFocused ? 'focused' : 'not focused'}
<textarea
ref={textArea}
value={data}
onChange={e => setData(e.target.value)}
/>
</div>
);
}
演示:Stackblitz
我是一名 Vue 开发人员,正在尝试开发 React 应用程序。
我正在尝试将 CodeMirror 包装在 React 应用程序中,但我 运行 遇到了一些麻烦。不确定如何修复它。
我正在实例化一个 CodeMirror 编辑器并将一些事件处理程序附加到它。
这些处理程序是这样的:
当您聚焦编辑器时,isFocused
变量变为 true
。
当您将焦点移出编辑器时,isFocused
变量变为 false
。
当您在编辑器中输入时,如果 isFocused
变量为真,您应该执行一些操作。
在最后一个处理程序中,我需要访问一个 reactive 变量集 useState
(isFocused
)。
该变量在该函数的上下文中不是反应性的。它被读取为默认值 false
.
组件看起来像这样:
import React, {useState, useEffect, useRef} from 'react';
import 'codemirror/lib/codemirror.css'
import 'codemirror/mode/javascript/javascript'
import CodeMirror from 'codemirror'
import './App.css';
function App() {
const textArea = useRef()
const [isFocused, setIsFocused] = useState(false)
const [data, setData] = useState('sample data')
const handleChange = () => {
console.log('isFocused->', isFocused);
if (isFocused) {
// do something here
}
}
const handleEditorFocus = () => {
setIsFocused(true)
}
const handleEditorBlur = () => {
setIsFocused(false)
}
useEffect(() => {
const editor = CodeMirror.fromTextArea(textArea.current)
editor.on('change', handleChange)
editor.on('focus', handleEditorFocus)
editor.on('blur', handleEditorBlur)
return () => {
editor.toTextArea()
}
}, []);
return (
<div>
{isFocused ? 'focused' : 'not focused'}
<textarea
ref={textArea}
value={data}
onChange={(e) => setData(e.target.value)}
></textarea>
</div>
)
};
export default App;
请指出这个问题的正确方向。
谢谢!
更新: 我什至做了一个 repl.it here.
更新 2
stackblitz 上更好的演示。
我基本上需要访问 handleChange
函数中的 instance
和 change
参数。
添加一个带有回调的 useEffect
函数到 handleChange
并将其作为参数传递 isFocused
。
PS: 不要忘记 Boolean()
显示 isFocused 的状态,否则它 returns 一个对象。
(参见页面底部的演示 link)
import React, { useState, useEffect, useRef } from 'react';
import 'codemirror/lib/codemirror.css';
import 'codemirror/mode/javascript/javascript';
import CodeMirror from 'codemirror';
export default function App() {
const textArea = useRef();
const [isFocused, setIsFocused] = useState(false);
const [data, setData] = useState('sample data');
const handleChange = isF => {
console.log('isFocused->', Boolean(isF)); // here
if (isFocused) {
// ...
}
};
const handleEditorFocus = () => {
setIsFocused(true);
};
const handleEditorBlur = () => {
setIsFocused(false);
};
useEffect(() => { // here
handleChange(isFocused);
}, [isFocused]);
useEffect(() => {
const editor = CodeMirror.fromTextArea(textArea.current);
editor.on('change', handleChange);
editor.on('focus', handleEditorFocus);
editor.on('blur', handleEditorBlur);
return () => {
editor.toTextArea();
};
}, []);
return (
<div>
{isFocused ? 'focused' : 'not focused'}
<textarea
ref={textArea}
value={data}
onChange={e => setData(e.target.value)}
/>
</div>
);
}
演示:Stackblitz