【发布时间】:2021-09-01 16:45:09
【问题描述】:
我有一个组件,我想在渲染之前运行一个非反应动画库。这使我无法采用仅使用标准隐藏/显示逻辑的标准路线。我最初尝试使用 ReactDOM.createPortal 但根本没有渲染组件。使用 ReactDOM.render,我已经让元素在动画完成后正确渲染,并且我能够成功地将更改传播到“父”状态,但状态更改不会传播回“子”状态.这是我的代码:
HTML
<div id="root"></div>
<div id="childPlaceholder"></div>
Javascript
import './App.css';
import React, { useEffect, useState } from 'react';
import ReactDOM from 'react-dom';
function App() {
const [data, updateData] = useState(0)
function add(val) {
console.log("add");
updateData(val);
}
function renderSubpage() {
let $el = document.getElementById("childPlaceholder");
// NonReactAnimationLibrary.ShowContainer($el);
ReactDOM.render(<Child number={data} add={add} />, $el);
// ReactDOM.createPortal(<Child number={data} add={add} />, $el);
}
return ( <>
<button onClick={renderSubpage}>
add child
</button>
<div> data: {data}</div>
</>
);
}
function Child(props) {
return <>
<button onClick={()=>{props.add(props.number + 1)}}>add number</button>
<div>child {props.number}</div>
</>
}
export default App;
是否可以在反应中做到这一点?
更新 1:
所以我更新了每个 Olivers 响应的代码,它使用门户正确呈现,但子组件仍然不会重新呈现父组件中的状态更改
const root = document.getElementById("root");
const childRoot = document.getElementById("childPlaceholder");
function Child(args) {
return ReactDOM.createPortal(<>
<div>child: {args.number}</div>
<button onClick={()=>{args.add(args.number+1)}}>Increment base number</button>
</>, childRoot);
}
export default class App extends React.Component {
constructor() {
super();
this.state = { data: 0, number:0 };
}
add = (val)=> {
this.setState({
...this.state,
number: val
});
}
addChild = () => {
this.setState(prevState => ({data: prevState.data + 1}));
}
render() {
const children = Array(this.state.data)
.fill()
.map((_, i) => <Child key={i} number={0} add={this.add}/>);
return (
<div>
<button onClick={this.addChild}>
add child
</button>
<div> data: {this.state.data}</div>
{children}
</div>
);
}
}
ReactDOM.render(<App/>, root);
更新 2:
找到了罪魁祸首。改变了
number={0}
到
number={this.state.number}
它可以工作
【问题讨论】:
-
你是什么意思:“传播回“孩子”?
-
Child 组件中的 {props.number} 值不会更新,而 App 组件中的 {data} 值会更新
-
这是
ReactDOM.createPortal的完美用例,我不明白为什么它不适合你,也许你没有正确使用它。 -
唯一的区别是我用相同的参数调用了 ReactDOM.createPortal 而不是 ReactDOM.render。这是正确的使用方法吗?我在帖子中添加了我尝试使用它的方式
-
ReactDOM.createPortal 必须使用inisde渲染方法,可以看文档reactjs.org/docs/portals.html
标签: javascript reactjs