和我一起实战 react 之与 DOM 有关的日子

1,010 阅读1分钟

大部分情况下你不需要查询DOM来更新UI

在与DOM有关的日子里还是有些怀念的,怀念的也许不仅是技术,而是怀念自己从一棵小白菜成长起来的过程,怀念那个年代的某些时光。

PS:不怀旧了,言归正传。大部分情况下你应该只需要关注setState方法来改变组件的状态,但有时候情况往往比较特殊,比如input.focus的时候。React给大家提供了两种方式来引用DOM对象。

注意:不管是findDOMNode还是refs你都应该在componentDidMount方法中使用,且在componentWillUnmount方法中解除引用关系。

findDOMNode

当你需要获得React组件的DOM对象时,你必须使用findDOMNode方法。

render(){
  return (
    
  );
}
componentDidMount(){
  console.log(findDOMNode(this.refs.imageButton))
}

refs

在外还有另外的一种方式,在DOM元素上通过ref引用来获得访问DOM元素的能力。

render (){
  return (
    
); } componentDidMount (){ console.log(this.refs.book) }

ref也支持函数,你可以在函数中做一些逻辑操作:


constructor (props){
  this.book = null;
}
render (){
  return (
    
{ this.book = v; }} >
); } componentWillUnmount (){ this.book = null; }

正确的使用姿势

在刨除了正常的情况下,在React中直接引用DOM,你应该在componentDidMount中引用,然后在componentWillUnmount中解除引用。

且让我们看一看,在React中如何使用像Swiper这样的jQuery插件。

const findDOMNode = ReactDOM.findDOMNode;
const Button = Kodo.Button;
const imageArray = [
        'http://content.battlenet.com.cn/wow/media/screenshots/screenshot-of-the-day/warlords-of-draenor/warlords-of-draenor-ss0602-large.jpg',
        'http://content.battlenet.com.cn/wow/media/screenshots/screenshot-of-the-day/warlords-of-draenor/warlords-of-draenor-ss0601-large.jpg',
        'http://content.battlenet.com.cn/wow/media/screenshots/screenshot-of-the-day/warlords-of-draenor/warlords-of-draenor-ss0600-large.jpg',
        'http://content.battlenet.com.cn/wow/media/screenshots/screenshot-of-the-day/warlords-of-draenor/warlords-of-draenor-ss0599-large.jpg',
        'http://content.battlenet.com.cn/wow/media/screenshots/screenshot-of-the-day/warlords-of-draenor/warlords-of-draenor-ss0598-large.jpg'
      ];
class ImageSlide extends React.Component{
  constructor(props){
    super(props);
    this.imageSlideContainer = null;
    this.imageSlideObject = null;
    this.HandlerWithMe = this.handlerMe.bind(this);

  }
  handlerMe (e){
    console.log(this);
  }
  render (){
    return (
      
click me

{ this.imageSlideContainer = c; }} className="swiper-wrapper" >
); } componentDidMount (){ console.log(this.imageSlideContainer); let swiperHtml = imageArray.map((v)=>{ return '
+v+' />'; }).join(''); this.imageSlideContainer.innerHTML = swiperHtml; this.imageSlideObject = new Swiper('.swiper-container',{ direction: 'vertical', loop: true, autoplay: 5000 }); } componentWillUnmount (){ this.imageSlideContainer = null; this.imageSlideObject = null; } } ReactDOM.render(( ),document.getElementById('app'));

像这样的方式,我建议将不适用虚拟DOM的部分,还是自己写成字符串插入到DOM中,如果你使用了React来描述,非常的不好控制状态。