TypeScript中的一些状态有问题发生反应。
子组件通过一个名为returnTerminal()
的传递函数将一个“终端”对象传递给父对象。然后将此终端对象存储为useState _object
。useEffect()
说_object
最终不是空的,但是callback()
一直坚持_object
是空的,我不知道为什么。
父组件
const Parent: React.FunctionComponent<ParentProps> = () => {
const [_object, set_object] = useState<Terminal>(null);
const handleGetTerminal = (terminal: Terminal) => {
set_object(terminal);
};
useEffect(() => {
if (_object !== null) {
_object.writeln("_object is not null"); // This prints just fine
}
}, [_object]);
return (
<Child
returnTerminal={(term) => handleGetTerminal(term)}
callback={() => {
console.log(_object === null); // This returns true - the object is null for some reason???
}}
/>
);
};
子组件
const Child: React.FunctionComponent<ChildProps> = (props) => {
const { callback, returnTerminal } = props;
// The ref where the terminal will be stored and returned
const ref = useRef<HTMLDivElement>(null);
// The xterm.js terminal object
const terminal = new Terminal();
useLayoutEffect(() => {
// Calls whenever terminal is typed into
if (callback) terminal.onData(callback);
// Mount terminal to the DOM
if (ref.current) terminal.open(ref.current);
// Pass the terminal to the parent object
returnTerminal(terminal);
}, []);
return <div ref={ref}></div>;
};
export default Child;
无论我等待多长时间,callback()
总是返回_object
为null。
发布于 2021-09-28 00:24:50
最终的答案是使用useImperativeHandle和forwardRef。这是完整的代码。
亲本
import Child from "./child";
interface ParentProps {
name?: string;
}
const Parent: React.FunctionComponent<ParentProps> = () => {
type ChildHandle = ElementRef<typeof Child>;
const childRef = useRef<Child>(null);
let _object: Terminal; // same Terminal type that Child uses
useEffect(() => {
if (childRef.current) {
_object = childRef.current.get(); // imperitive handle function
_object.writeln(“_object loaded”);
}
}, []);
return (
<Child
ref={childRef}
callback={() => {
terminal.writeln("_object is not null”); // THIS finally works
}}
/>
);
};
儿童
interface ChildProps {
callback?(data: string): void;
}
type ChildHandle = {
get: () => Terminal;
};
const Child: ForwardRefRenderFunction<ChildHandle, ChildProps> = (
props,
forRef
) => {
const { callback } = props;
const terminal = new Terminal();
// The ref where the terminal will be stored and returned
const ref = useRef<HTMLDivElement>(null);
useImperativeHandle(forRef, () => ({
get() {
return terminal;
},
}));
useLayoutEffect(() => {
// Calls whenever terminal is typed into
if (callback) terminal.onData(callback);
// Mount terminal to the DOM
if (ref.current) terminal.open(ref.current);
}, []);
return <div ref={ref}></div>;
};
export default forwardRef(Child);
https://stackoverflow.com/questions/69337363
复制相似问题