이 글은 주로 React가 특정 DOM 노드에 컴포넌트를 렌더링하는 방법에 대한 관련 정보를 소개합니다. 이 글은 샘플 코드를 통해 이를 매우 자세하게 소개합니다. 이는 모든 사람의 학습이나 작업에 대한 특정 참조 학습 가치가 있습니다. 아래에서 에디터와 함께 배워보겠습니다.
머리말
React의 장점 중 하나는 API가 특히 간단하다는 점을 우리 모두 알고 있습니다. 간단한 함수처럼 render 메소드를 통해 컴포넌트의 기본 구조를 반환하면 재사용 가능한 React 컴포넌트를 얻을 수 있습니다. 그러나 때로는 여전히 몇 가지 제한 사항이 있습니다. 특히 API에는 구성 요소가 렌더링되어야 하는 DOM 노드를 제어할 수 없어 일부 탄력적 레이어 구성 요소를 제어하기 어렵게 만듭니다. 상위 요소가 overflow:hidden
으로 설정된 경우 문제가 발생합니다. overflow:hidden
的时候,问题就会出现了。
例如就像下面的这样:
我们实际期待的效果是这样的:
幸运的是,虽然不是很明显,但有一个相当优雅的方式来绕过这个问题。我们学到的第一个react函数是render 方法,他的函数签名是这样的:
ReactComponent render( ReactElement element, DOMElement container, [function callback] )
通常情况下我们使用该方法将整个应用渲染到一个DOM节点中。好消息是该方法并不仅仅局限于此。我们可以在一个组件中,使用ReactDom.render
方法将另一个组件渲染到一个指定的DOM 元素中。作为一个组件的render 方法,其必须是纯净的(例如:不能改变state或者与DOM交互).所以我们需要在componentDidUpdate 或者 componentDidMount 中调用ReactDom.render
다행히도 즉시 명확하지는 않지만 이 문제를 해결할 수 있는 상당히 우아한 방법이 있습니다. 우리가 배운 첫 번째 반응 함수는 render 메서드이고 그의 함수 서명은 다음과 같습니다:
import React,{Component} from 'react'; import ReactDom from 'react-dom'; export default class RenderInBody extends Component{ constructor(p){ super(); } componentDidMount(){//新建一个p标签并塞进body this.popup = document.createElement("p"); document.body.appendChild(this.popup); this._renderLayer(); } componentDidUpdate() { this._renderLayer(); } componentWillUnmount(){//在组件卸载的时候,保证弹层也被卸载掉 ReactDom.unmountComponentAtNode(this.popup); document.body.removeChild(this.popup); } _renderLayer(){//将弹层渲染到body下的p标签 ReactDom.render(this.props.children, this.popup); } render(){ return null; } }
ReactDom.render
메서드를 사용하여 다른 구성 요소를 지정된 DOM 요소로 렌더링할 수 있습니다. 컴포넌트의 렌더링 메소드는 순수해야 합니다(예를 들어 상태를 변경하거나 DOM과 상호작용할 수 없음). 따라서 우리는 componentDidUpdate 또는 componentDidMount에서 ReactDom.render
메소드를 호출해야 합니다. 또한 상위 요소가 언로드되면 수정된 구성 요소도 언로드되는지 확인해야 합니다.
정리한 후 다음 구성 요소를 얻습니다.
export default class Dialog extends Component{
render(){
return {
<RenderInBody>i am a dialog render to body</RenderInBody>
}
}
}
componentDidMount에서 수동으로 p 태그를 본문에 삽입한 다음 ReactDom.render를 사용하여 구성 요소를 p 태그로 렌더링할 때
컴포넌트를 본문에 직접 렌더링하려면 RenderInBody 레이어만 래핑하면 됩니다. 그게 바로 컴포넌트 외부입니다.
//此组件用于在body内渲染弹层
import React,{Component} from 'react'
import ReactDom from 'react-dom';
export default class RenderInBody extends Component{
constructor(p){
super(p);
}
componentDidMount(){
/**
popupInfo={
rootDom:***,//接收弹层组件的DOM节点,如document.body
left:***,//相对位置
top:***//位置信息
}
*/
let {popupInfo} = this.props;
this.popup = document.createElement('p');
this.rootDom = popupInfo.rootDom;
this.rootDom.appendChild(this.popup);
//we can setAttribute of the p only in this way
this.popup.style.position='absolute';
this.popup.style.left=popupInfo.left+'px';
this.popup.style.top=popupInfo.top+'px';
this._renderLayer()
}
componentDidUpdate() {
this._renderLayer();
}
componentWillUnmount(){
this.rootDom.removeChild(this.popup);
}
_renderLayer(){
ReactDom.render(this.props.children, this.popup);
}
render(){
return null;
}
}
export default (dom,classFilters)=> { let left = dom.offsetLeft, top = dom.offsetTop + dom.scrollTop, current = dom.offsetParent, rootDom = accessBodyElement(dom);//默认是body while (current !=null ) { left += current.offsetLeft; top += current.offsetTop; current = current.offsetParent; if (current && current.matches(classFilters)) { rootDom = current; break; } } return { left: left, top: top ,rootDom:rootDom}; } /*** 1. dom:为响应弹层的dom节点,或者到该dom的位置后,可以做位置的微调,让弹层位置更佳合适 * 2. classFilters:需要接收弹层组件的DOM节点的筛选类名 /
위 내용은 지정된 DOM 노드에 구성 요소를 렌더링하는 React의 방법에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!