2015-06-12 19 views

Odpowiedz

29

Myślę, że najbardziej intuicyjnym sposobem na zrobienie tego jest zapewnienie dzieciom "oczekiwania" prop, który ukrywa komponent przez czas, jaki upłynął od rodzica. Po ustawieniu domyślnego stanu na ukryty, React nadal będzie renderował komponent natychmiast, ale nie będzie widoczny, dopóki stan się nie zmieni. Następnie możesz ustawić componentWillMount, aby wywołać funkcję, aby pokazać ją po upływie czasu, jaki został przekazany za pomocą rekwizytów.

var Child = React.createClass({ 
    getInitialState : function() { 
     return({hidden : "hidden"}); 
    }, 
    componentWillMount : function() { 
     var that = this; 
     setTimeout(function() { 
      that.show(); 
     }, that.props.wait); 
    }, 
    show : function() { 
     this.setState({hidden : ""}); 
    }, 
    render : function() { 
     return (
      <div className={this.state.hidden}> 
       <p>Child</p> 
      </div> 
     ) 
    } 
}); 

Następnie, w komponencie nadrzędnym, wystarczy, że przekażesz czas, jaki dziecko ma czekać przed wyświetleniem.

var Parent = React.createClass({ 
    render : function() { 
     return (
      <div className="parent"> 
       <p>Parent</p> 
       <div className="child-list"> 
        <Child wait={1000} /> 
        <Child wait={3000} /> 
        <Child wait={5000} /> 
       </div> 
      </div> 
     ) 
    } 
}); 

Here's a demo

+0

Dziękuję bardzo za odpowiedź! Działa dokładnie tak, jak potrzebowałem. – michalvalasek

+0

skąd masz tę nieruchomość z show? to nie jest część React? – PositiveGuy

+0

'show' odnosi się do utworzonej przeze mnie funkcji, która ustawia stan' hidden' na pusty ciąg znaków. To trzecia funkcja w klasie "Dziecko". –

7

W komponentu ojca <Father /> można utworzyć początkowy stan, w którym można śledzić każde dziecko (przy użyciu i id na przykład), przypisując wartość logiczną, co oznacza, tynku lub nie:

getInitialState() { 
    let state = {}; 
    React.Children.forEach(this.props.children, (child, index) => { 
     state[index] = false; 
    }); 
    return state; 
} 

Potem, kiedy składnik jest zamontowany, zaczynasz swoje czasomierze, aby zmienić stan:

componentDidMount() { 
    this.timeouts = React.Children.forEach(this.props.children, (child, index) => { 
     return setTimeout(() => { 
       this.setState({ index: true; }); 
     }, child.props.delay); 
    }); 
} 

Podczas renderowania swoje dzieci, to zrobić poprzez ich odtworzenie, przypisując jako rekwizyt stanu dla dziecka dopasowania, które mówi, że jeśli składnik musi być wydane lub nie.

let children = React.Children.map(this.props.children, (child, index) => { 
    return React.cloneElement(child, {doRender: this.state[index]}); 
}); 

Więc w składniku

render() { 
    if (!this.props.render) return null; 
    // Render method here 
} 

Kiedy oczekiwanie jest zwolniony <Child /> stan ulega zmianie, a składnik ojciec rerendered. Rekwizyty dla dzieci są aktualizowane, a jeśli doRender jest true, będą się renderować.

+0

Dziękuję bardzo za odpowiedź! Chociaż wybrałem odpowiedź Michaela (ponieważ było to trochę lepiej dopasowane do mojej sytuacji), twoja odpowiedź jest ** również poprawna ** i może być odpowiednia dla kogoś, kto to czyta. Wielkie dzięki za poświęcony czas! – michalvalasek

+0

Zawsze chętnie pomogę ... i mimo to może sprzyjać wszelkim przyszłym myślom :) – gcedo

2

Zależy od przypadku użycia.

Jeśli chcesz zrobić animację dzieci mieszania się, użyj reagować animacja dodatek: https://facebook.github.io/react/docs/animation.html Inaczej dokonać renderowania dzieci pozostających na rekwizyty i dodać rekwizyty po pewnym opóźnieniem.

Nie opóźniłbym składnika, ponieważ prawdopodobnie będzie Cię prześladować podczas testowania. Idealne składniki powinny być czyste.

0

Mój przypadek użycia może być nieco inny, ale pomyślałem, że może być użyteczne opublikowanie rozwiązania, które wymyśliłem, ponieważ wymaga innego podejścia.

Zasadniczo mam element strony Popover innej firmy, który przyjmuje element DOM zakotwiczenia jako prop. Problem polega na tym, że nie mogę zagwarantować, że element kotwiący pojawi się natychmiast, ponieważ element kotwiący staje się widoczny w tym samym czasie, co element Popover, który chcę do niego zakotwiczyć (podczas tej samej wysyłki redux).

Jedną z możliwych poprawek było umieszczenie elementu Popover głębiej w drzewie komponentów niż element, który miał zostać zakotwiczony. Jednak nie pasowało to do logicznej struktury moich komponentów.

Ostatecznie zdecydowałem się opóźnić (ponownie) renderowanie komponentu Popover, aby upewnić się, że można znaleźć zakotwiczony element DOM. Wykorzystuje funkcję jako wzorzec dla dzieci, aby uczynić tylko dzieci po ustalonym opóźnieniem:

import { Component } from 'react' 
import PropTypes from 'prop-types' 

export default class DelayedRender extends Component { 
    componentDidMount() { 
     this.t1 = setTimeout(() => this.forceUpdate(), 1500) 
    } 

    componentWillReceiveProps() { 
     this.t2 = setTimeout(() => this.forceUpdate(), 1500) 
    } 

    shouldComponentUpdate() { 
     return false 
    } 

    componentWillUnmount() { 
     clearTimeout(this.t1) 
     clearTimeout(this.t2) 
    } 

    render() { 
     return this.props.children() 
    } 
} 

DelayedRender.propTypes = { 
    children: PropTypes.func.isRequired 
} 

Może być używany tak:

<DelayedRender> 
    {() => 
     <Popover anchorEl={getAnchorElement()}> 
      <div>Hello!</div> 
     </Popover> 
    )}} 
</DelayedRender> 

czuje się całkiem hacky do mnie, ale pracuje dla mojego przypadku użycia Niemniej jednak.

Powiązane problemy