2015-04-28 4 views
28

Мы столкнулись с некоторыми проблемами при использовании реакции сейчас, но это kinda кипит к одной части того, как мы использовали реакцию.Показать/скрыть компоненты в ReactJS

Как мы должны показывать/скрывать дочерние компоненты?

Это, как мы закодировали его (это есть только фрагменты наших компонентов) ...

_click: function() { 
    if ($('#add-here').is(':empty')) 
    React.render(<Child />, $('#add-here')[0]); 
    else 
    React.unmountComponentAtNode($('#add-here')[0]); 
}, 
render: function() { 
    return(
    <div> 
     <div onClick={this._click}>Parent - click me to add child</div> 
     <div id="add-here"></div> 
    </div> 
) 
} 

и в последнее время я читал примеры, как это должен был быть где-то вдоль этой линии:

getInitialState: function() { 
    return { showChild: false }; 
}, 
_click: function() { 
    this.setState({showChild: !this.state.showChild}); 
}, 
render: function() { 
    return(
    <div> 
     <div onClick={this._click}>Parent - click me to add child</div> 
     {this.state.showChild ? <Child /> : null} 
    </div> 
) 
} 

Должен ли я использовать этот React.render()? Кажется, что останавливает различные вещи, такие как shouldComponentUpdate, каскадом для ребенка и такими вещами, как e.stopPropagation ...

+1

Можете ли вы объяснить более подробно, что проблема с 2-го решения есть? Это действительно предпочтительный способ сделать. Имейте атрибут состояния 'showChild', который вы переключаете, когда вы нажимаете' div'. При вызове 'setState' выполняется повторная передача вашего компонента. –

+0

@LarsBlumberg. Ой. У меня на самом деле еще не было опыта со вторым решением. Я только пробовал это в маленьком приложении и, похоже, работает. Мы использовали первый, так как это было то, чему нас учили раньше. Но теперь мы столкнулись с такими проблемами, как «stopPropagation», которые не работают, или нам необходимо вручную обновить Child, когда 'parentComponentUpdate' запускает родительский элемент. Но я действительно не видел никаких документов относительно этого «предпочтительного способа», только примеры различных учебников. Итак, мы должны использовать второе решение? – index

+1

Да, второй - лучший выбор. Документы и примеры React не используют JQuery. Документы имеют много отличной информации. https://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html – WiredPrairie

ответ

56

Я представил рабочий пример, следующий за вашим вторым подходом. Обновление состояния компонента - это предпочтительный способ показать/скрыть детей.

Учитывая у вас есть этот контейнер:

<div id="container"> 
</div> 

вы можете использовать современные Javascript (ES6, первый пример) или классический JavaScript (ES5, второй пример) для реализации логики компоненты:

Показать/компоненты скрыть с помощью ES6

Try this demo live on JSFiddle

class Child extends React.Component { 
    render() { 
    return (<div>I'm the child</div>); 
    } 
} 

class ShowHide extends React.Component { 
    constructor() { 
    super(); 
    this.state = { 
     childVisible: false 
    } 
    } 

    render() { 
    return (
     <div> 
     <div onClick={() => this.onClick()}> 
      Parent - click me to show/hide my child 
     </div> 
     { 
      this.state.childVisible 
      ? <Child /> 
      : null 
     } 
     </div> 
    ) 
    } 

    onClick() { 
    this.setState(prevState => ({ childVisible: !prevState.childVisible })); 
    } 
}; 

React.render(<ShowHide />, document.getElementById('container')); 

Показать компоненты/скрыть с помощью ES5

Try this demo live on JSFiddle

var Child = React.createClass({ 
    render: function() { 
    return (<div>I'm the child</div>); 
    } 
}); 

var ShowHide = React.createClass({ 
    getInitialState: function() { 
    return { childVisible: false }; 
    }, 

    render: function() { 
    return (
     <div> 
     <div onClick={this.onClick}> 
      Parent - click me to show/hide my child 
     </div> 
     { 
      this.state.childVisible 
      ? <Child /> 
      : null 
     } 
     </div> 
    ) 
    }, 

    onClick: function() { 
    this.setState({childVisible: !this.state.childVisible}); 
    } 
}); 

React.render(<ShowHide />, document.body); 
+1

Это действительно приятно. Я хотел бы реализовать это. Однако мне также нужно удалить ребенка, если он был нажат иначе, чем дочерний компонент. Не могли бы вы посоветовать мне, как? – Karl

+0

@LarsBlumberg Да, я спросил [здесь] (http://stackoverflow.com/questions/38158005/insert-a-component-when-clicked-and-remove-the-componet-when-click-other-than- е). Не могли бы вы мне помочь. Спасибо. – Karl

+0

Это последнее использование ES6 https://youtu.be/Mo2_UPkZjJU – Prem

0
/* eslint-disable jsx-a11y/img-has-alt,class-methods-use-this */ 
import React, { Component } from 'react'; 
import PropTypes from 'prop-types'; 
import todoStyle from 'src/style/todo-style.scss'; 
import { Router, Route, hashHistory as history } from 'react-router'; 
import Myaccount from 'src/components/myaccount.jsx'; 

export default class Headermenu extends Component { 

    constructor(){ 
    super(); 

    // Initial state 
    this.state = { open: false }; 

} 

toggle() { 
    this.setState({ 
    open: !this.state.open 
    }); 
} 

    componentdidMount() { 
    this.menuclickevent = this.menuclickevent.bind(this); 
    this.collapse = this.collapse.bind(this); 
    this.myaccount = this.myaccount.bind(this); 
    this.logout = this.logout.bind(this); 
    } 

    render() { 
    return (
     <div> 

     <div style={{ textAlign: 'center', marginTop: '10px' }} id="menudiv" onBlur={this.collapse}> 
      <button onClick={this.toggle.bind(this)} > Menu </button> 

      <div id="demo" className={"collapse" + (this.state.open ? ' in' : '')}> 
      <label className="menu_items" onClick={this.myaccount}>MyAccount</label> 
      <div onClick={this.logout}> 
       Logout 
      </div> 
      </div> 

     </div> 
     </div> 
    ); 
    } 

    menuclickevent() { 
    const listmenu = document.getElementById('listmenu'); 
    listmenu.style.display = 'block'; 
    } 



    logout() { 
    console.log('Logout'); 
    } 
    myaccount() { 
    history.push('/myaccount'); 
    window.location.reload(); 

    } 


}