Как вы получаете доступ к DOMNodes / refs потомков в компоненте оболочки React? - PullRequest
0 голосов
/ 24 октября 2018
class List extends Component {
   <DoSomethingToList>
    {this.props.list.map(item => <Item key={item} ref={item} />}
   </DoSomethingToList>
}

class DoSomethingToList extends Component {

  componentDidUpdate(prevProps) {
     // I want to access refs here
     let refs = this.refs
     // refs === {} ------>   Why is this happening?
  }
   render() {
     <div>
       {this.props.children}
     </div>
   }  

}

Я хочу иметь доступ к дочерним элементам в качестве ссылок в методах жизненного цикла компонента оболочки.Это так, я могу отслеживать предыдущие экземпляры domNode для анимации.Но всякий раз, когда я обращаюсь к ссылкам, они возвращаются как пустой объект.Что такое дружественный к React способ доступа к ссылкам в методах жизненного цикла?

1 Ответ

0 голосов
/ 24 октября 2018

Родительский / контейнерный компонент (DoSomethingToList) должен отслеживать ссылки.

const List = ({list}) => (
    <DoSomethingToList>
    {ctx => (
        list.map((item) => <Item key={item} ref={ctx.refs[item]} />)
    )}
    </DoSomethingToList>
)

class DoSomethingToList extends Component {
    state = {refs: []};

    componentDidUpdate(prevProps, prevState) {
        let refs = prevState.refs;
        // do something with refs...
    }

    render() {
      <div>
          {this.props.children(this.state)}
      </div>
    }  
}

Честно говоря, это плохая практика, поскольку React не будет знать, содержится ли какое-либо состояние элемента у каждого ref change.

Поэтому я бы рекомендовал предоставить обратный вызов, который дочерний компонент может вызвать, чтобы сообщить родителю об изменении обратно родителю.

const List = ({list}) => (
    <DoSomethingToList>
    {ctx => (
        list.map((item) => 
            <Item key={item} value={ctx.values[item]} onUpdate={ctx.updateValue} />)
    )}
    </DoSomethingToList>
)

class DoSomethingToList extends Component {
    state = { 
        values: [],
        updateValue: this.updateValue
    };

    updateValue = (value, i) => {
        const {values} = prevState;
        const newValues = {...values};
        newValues[i] = value;
        this.setState({values: newValues});
    }

    componentDidUpdate(prevProps, prevState) {
        const {values} = prevState;
        // do something with values...
    }
    render() {
    <div>
        {this.props.children(this.state)}
    </div>
    }  
}
...