DOM结构:
<View style={stylescheckContainer} ref='checkContainer' onLayout={({nativeEvent:e})=>thislayout(e)}>
</View>
对应js方法:
layout=(e)=>{
consolewarn(elayouty) ;
var UIManager = require('UIManager');
consolewarn(etarget);
UIManagermeasure(etarget, (x, y, width, height, left, top) => {
consolewarn('x:'+x)
consolewarn('y:'+y)
consolewarn('width:'+width)
consolewarn('height:'+height)
consolewarn('left:'+left)
consolewarn('top:'+top)
})
}
注意:View组件的onLayout(可以得到宽高和相对位置)配合UIManagermeasure(可以得到宽高和绝对位置)一起使用
附加知识点:
得到某一dom元素的节点值:
import {findNodeHandle} from 'react-native';
var nodeData = findNodeHandle(thisrefsname);
nodeData即为节点值
一、选取 DOM 元素
在 jQuery 中,我们已经熟悉了使用 sizzle 选择器来完成 DOM 元素的选取。而在 React 中,我们可以使用 ref 来更有针对性的获取元素。
import React from 'react';class Demo extends ReactCompoent {
getDomNode() { return thisrefsroot; // 获取 Dom Node }
render() { return ( <div ref="root">just a
demo</div> ); }}
这是最简单的获取 node 的方式,如果有多层结构嵌套呢?没有关系。
import React from 'react';class Demo extends ReactCompoent {
getRootNode() { return thisrefsroot; // 获取根节点 Dom Node }
getLeafNode() { return thisrefsleaf; // 获取叶节点 Dom Node }
render() { return ( <div ref="root">
<div ref="leaf">just a demo</div>
</div> ); }}
如果是组件和组件嵌套呢?也没关系,父组件仍然可以拿到子组件的根节点。
import React from 'react';import ReactDOM from 'react-dom';class Sub
extends ReactCompoent { render() { return (
<div>a sub component</div> ); }}class Demo extends
ReactCompoent { getDomNode() { return thisrefsroot; // 获取
Dom Node } getSubNode() { return
ReactDOMfindDOMNode(thisrefssub); // 获取子组件根节点 } render() {
return ( <div ref="root"> <Sub
ref="sub" /> </div> ); }}
上面使用了比较易懂的 API 来解释 Ref 的用法,但里面包含了一些现在 React 不太推荐和即将废弃的方法,如果用 React 推荐的写法,我们可以这样写。
import React from 'react';import ReactDOM from 'react-dom';class Sub
extends ReactCompoent { getDomNode() { return thisrootNode;
} render() { return ( <div ref={(c) =>
thisrootNode = c}>a sub component</div> ); }}class
Demo extends ReactCompoent { getDomNode() { return
thisrootNode; // 获取 Dom Node } getSubNode() { return
thissubgetDomNode(); // 获取子组件根节点 } render() { return (
<div ref={(c) => thisrootNode = c}>
<Sub ref={(c) => thissub = c} /> </div>
); }}
有人可能会问,那子组件怎么拿父组件的 Dom Node 呢,从 React
的单向数据流角度出发,遇到这种情况我们应该通过回调通知给父组件,再由父组件自行判断如何修改 Node,其实父组件拿子组件的 Node
情况也很少,大多数情况下我们是通过 props 传递变化给子组件,获取子组件
Node,更多的情况下是为了避开大量重新渲染去修改一些Node的属性(比如 scrollLeft)。
二、DOM *** 作
jQuery 中提供了丰富的 *** 作方法,但一个个 *** 作 DOM 元素有的时候真的很烦人并且容易出错。React 通过数据驱动的思想,通过改变 view 对应的数据,轻松实现 DOM 的增删 *** 作。
class Demo extends ReactCompoent { constructor(props) {
super(props); thisstate = { list: [1, 2, 3],
}; thisaddItemFromBottom = thisaddItemFromBottombind(this);
thisaddItemFromTop = thisaddItemFromTopbind(this);
thisdeleteItem = thisdeleteItembind(this); }
addItemFromBottom() { thissetState({ list:
thisstatelistconcat([4]), }); } addItemFromTop() {
thissetState({ list: [0]concat(thisstatelist),
}); } deleteItem() { const newList =
[thisstatelist]; newListpop(); thissetState({
list: newList, }); } render() { return (
<div> {thisstatelistmap((item) =>
<div>{item}</div>)} <button
onClick={thisaddItemFromBottom}>尾部插入 Dom 元素</button>
<button onClick={thisaddItemFromTop}>头部插入 Dom
元素</button> <button
onClick={thisdeleteItem}>删除 Dom 元素</button>
</div> ); }} 三、事件的监听
React 通过根节点代理的方式,实现了一套很优雅的事件监听方案,在组件 unmount 时也不需要自己去处理内存回收相关的问题,非常的方便。
import React from 'react';class Demo extends ReactComponent {
constructor(props) { super(props); thishandleClick =
thishandleClickbind(this); } handleClick() {
alert('我是d窗'); } render() { return ( <div
onClick={thishandleClick}>点击我d出d框</div> ); }}
这里有一个小细节就是
bind 的时机,bind 是为了保持相应函数的上下文,虽然也可以在 onClick 那里 bind,但这里选择在 constructor 里
bind 是因为前者会在每次 render 的时候都进行一次 bind,返回一个新函数,是比较消耗性能的做法。
但
React 的事件监听,毕竟只能监听至 root component,而我们在很多时候要去监听 window/document 上的事件,如果
resize、scroll,还有一些 React 处理不好的事件,比如
scroll,这些都需要我们自己来解决。事件监听为了屏蔽差异性需要做很多的工作,这里像大家推荐一个第三方库来完成这部分的工作,
add-dom-event-listener ,用法和原生的稍有区别,是因为这个库并不旨在做 polyfill,但用法还是很简单。
var addEventListener = require('add-dom-event-listener');var handler =
addEventListener(documentbody, 'click', function(e){
consolelog(etarget); // works for ie consolelog(enativeEvent); //
native dom event});handlerremove(); // detach event listener
另一个选择是 bean ,达到了 IE6+ 级别的兼容性。
四、事件的触发
和事件监听一样,无论是 Dom 事件还是自定义事件,都有很优秀的第三方库帮我们去处理,如果是 DOM 事件,推荐 bean ,如果是自定义事件的话,推荐 PubSubJS 。
五、documentready
React
作为一个 view 层框架,通常情况下页面只有一个用于渲染 React 页面组件的根节点 div,因此
documentready,只需把脚本放在这个 div 后面执行即可。而对于渲染完成后的回调,我们可以使用 React 提供的
componentDidMount 生命周期。
import React from 'react';class Demo
extends ReactComponent { constructor(props) { super(props);
} componentDidMount() { doSomethingAfterRender(); //
在组件渲染完成后执行一些 *** 作,如远程获取数据,检测 DOM 变化等。 } render() { return (
<div>just a demo</div> ); }} 六、attr 方法
jQuery 使用 attr 方法,获取 Dom 元素的属性。在 React 中也可以配合 Ref 直接读取 DOM 元素的属性。
import React from 'react';class Demo extends ReactComponent {
constructor(props) { super(props); }
componentDidMount() { thisrootNodescrollLeft = 10; //
渲染后将外层的滚动调至 10px } render() { return ( <div
ref={(c) => thisrootNode = c}
style={{ width: '100px', overflow: 'auto' }} >
<div style={{ width: '1000px' }}>just a demo</div>
</div> ); }}
但是,在大部分的情况下,我们完全不需要做,因为 React 的单向数据流和数据驱动渲染,我们可以不通过 DOM,轻松拿到和修改大部分我们需要的 DOM 属性。
import React from 'react';class Demo extends ReactComponent {
constructor(props) { super(props); thisstate = {
link: '//>
组件本身即上面两种 React 组件构建方法中的 render 方法。
我们可以通过thispropsxx的形式获取组件对象的属性,对象的属性可以任意定义,但要避免与JavaScript关键字冲突。
组件可以定义初始值,自己不可更改props属性值,只允许从父组件中传递过来:
父组件向子组件传递name="name"的props属性,在子组件中使用thispropsname引用此属性。
属性类型prop type和默认属性 default prop可以通过类中的 static来声明:
组件用来改变自己状态的属性,通常使用setState({key:value})来改变属性值触发界面刷新,不能使用thisstatexxx来直接改变。 典型的场景是在接收到服务器返回的新数据,或者在用户输入数据之后。
对于经常改变的数据且需要刷新界面显示,可以使用state。
对于不需要改变的属性值可以使用props。
React 最大的特色是当View层在渲染的时候,它不会直接从模板里面去构建一个DOM节点 首先, 它创建一些暂时的, 虚拟的 DOM, 然后和真实的DOM还有创建的Diffs一起做对比, 然后才决定需不需要渲染。
生命周期:广义上 => 各种客观事物的阶段性变化及其规律。生命体的周期是单一,不可逆,而软件开发的生命周期会根据方法的不同在完成前重新开始。
初始化阶段可以使用的函数:
getDefaultProps : 只调用一次,实例之间共享引用
getInitialState : 初始化每个实例特有的状态
componentWillMount : render之前最后一次修改状态的机会。如果在这个方法内调用setState,render()将会感知到更新后的state,将会执行仅一次,尽管state改变了。
render : 只能访问thisprops和thisstate,只有一个顶层组件,不允许修改状态和DOM输出
componentDidMount : 成功render并渲染完成真实DOM之后触发,可以修改DOM
调用顺序
当组件在客户端被实例化,第一次被创建时,以下方法依次被调用:
react-redux 库提供了一个组件和一个 API 帮助 Redux 和 React 进行绑定,
一个是 React 组件 <Provider/> ,一个是 connect()。
<Provider/> 接受一个 store 作为props,它是整个 Redux 应用的顶层组件,
connect() 提供了在整个 React 应用的任意组件中获取 store 中数据的功能。
它们一个将组件与redux关联起来,一个将store传给组件。组件通过dispatch发出action,store根据action的type属性调用对应的reducer并传入state和这个action,reducer对state进行处理并返回一个新的state放入store,connect监听到store发生变化,调用setState更新组件。
流程:
一、Provider组件接受redux的store作为props,然后通过context往下传。
二、connect函数收到Provider传出的store,然后接受三个参数mapStateToProps,mapDispatchToProps和组件,并将state和actionCreator以props传入组件,这时组件就可以调用actionCreator函数来触发reducer函数返回新的state,connect监听到state变化调用setState更新组件并将新的state传入组件。
connect(state => state, action)(Component);
1字符串
通过 thisrefsdemo 来引用真实dom的节点,建议不要使用它,因为字符串引用有一些问题,被认为是遗留问题,很可能会在未来的某个版本中删除。新版好像不推荐这样使用了
<input ref="demo" type ="text" placeholder='点击之后提示数据'/>
2回调函数(内联形式)
回调函数就是在dom节点或组件上挂载函数,函数的入参是dom节点或组件实例,达到的效果与字符串形式是一样的,都是获取其引用。(实际开发中使用的比较多)
<input ref={(currentNode)=>{thisinput1=currentNode}} type="text" placeholder='点击之后提示数据'/>
3回调函数(外联形式)
<input ref={thissaveInput} type="text" placeholder='点击之后提示数据'/>
saveInput=(current)=>{
consolelog(current)
thisinput1=current
}
4ReactcreateRef()
ReactcreateRef()是React 163之后引入的新API。如果您使用的是早期版本的React,我们建议您使用回调引用。Refs是使用属性创建的,ReactcreateRef()并通过ref属性附加到React元素。在构造组件时,通常将Refs分配给实例属性,以便可以在整个组件中引用它们。
<input ref={thismyRef1} type="text" placeholder='点击提示createRef'/>
myRef1= ReactcreateRef() //专人专用每次都只能一次,
myRef2= ReactcreateRef() //专人专用每次都只能一次,
获取input的值:consolelog(thismyRefcurrentvalue)
React 官方文档中如此声明:"如果你目前还在使用 thisrefstextInput 这种方式访问 refs ,我们建议用回调函数或 createRef API 的方式代替。" 为何如此糟糕?
自行百度吧、因为我也不知道!!!!
以上就是react中ref一些总结、希望能帮到一些同学们
以上就是关于react-native 获取某一元素的绝对位置(相对于屏幕左上角)全部的内容,包括:react-native 获取某一元素的绝对位置(相对于屏幕左上角)、如何在 React 中做到 jQuery-free、React分享等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)