javascript - How do I access children components of a reference in React Native Web? - Stack Overflow

I have some references in a React Native Web application - these references work on React Native, but n

I have some references in a React Native Web application - these references work on React Native, but not RNW.

For example, I have this code:

this.highlight.current._children[i].setNativeProps({ style: { backgroundColor: "black" } });
this.highlight.current._children[i]._children[0]._children[0].setNativeProps({ style: { color: "white" } })
this.highlight.current._children[i]._children[1]._children[0].setNativeProps({ style: { color: "white" } })

Which is based on this:

this.highlight = React.createRef();

Which is passed into a child ponent as a prop and used as such:

<View ref={this.props.highlight}>

It has several children (who have nested children as well).

However, on the web, there is no ._children at all.

How do I access children?

It's possible to do DOM manipulation directly if Platform.OS === 'web':

let dom = ReactDOM.findDOMNode(this.highlight.current);
... DOM manipulations

But this feels messy and code-duplicating if not absolutely necessary. I'd much rather apply my modifications to the reference directly via the React Native API.

EDIT: More code - here's my structure and a few relevant functions to the problem. I cut out irrelevant parts to try to make the code I posted smaller

class DetailBody extends Component {
  constructor() {
    super();
}

  render() {

    return (
      <ScrollView >
        <Text>{this.props.article.intro}</Text>
        <View ref={this.props.highlight}>
          {this.props.article.json.results.map((content, index) => (
            <View key={index} style={{}}>
              {content.pinyin ? (
                <Fragment>
                  <View>
                    <Text>
                      {content.pinyin}
                    </Text>
                  </View>
                  <View>
                    <Text>
                      {content.simplified}
                    </Text>
                  </View>
                </Fragment>
              ) : (
                  <Fragment>
                    <View>
                      <Text>
                      </Text>
                    </View>
                    <View>
                      <Text>
                        {content.characters}
                      </Text>
                    </View>
                  </Fragment>
                )
              }

            </View>
          ))}
        </View>
      </ScrollView>
    )
  }
}

class Detail extends Component {
  constructor() {
    super();
    this.state = {
      currentVal: 0,
    };
    this.traverseCharacters = this.traverseCharacters.bind(this)
    this.highlight = React.createRef();
  }

  async traverseCharacters(i) {

    this.highlight.current._children[i].setNativeProps({ style: { backgroundColor: "black" } });
    this.highlight.current._children[i]._children[0]._children[0].setNativeProps({ style: { color: "white" } })
    this.highlight.current._children[i]._children[1]._children[0].setNativeProps({ style: { color: "white" } })
    if (i > 0) {
      this.clearCharacters(i)
    }
  }

  render() {

    return (
        <DetailBody {...this.props} article={this.state.article} highlight={this.highlight} />
    );
  }
}

I have some references in a React Native Web application - these references work on React Native, but not RNW.

For example, I have this code:

this.highlight.current._children[i].setNativeProps({ style: { backgroundColor: "black" } });
this.highlight.current._children[i]._children[0]._children[0].setNativeProps({ style: { color: "white" } })
this.highlight.current._children[i]._children[1]._children[0].setNativeProps({ style: { color: "white" } })

Which is based on this:

this.highlight = React.createRef();

Which is passed into a child ponent as a prop and used as such:

<View ref={this.props.highlight}>

It has several children (who have nested children as well).

However, on the web, there is no ._children at all.

How do I access children?

It's possible to do DOM manipulation directly if Platform.OS === 'web':

let dom = ReactDOM.findDOMNode(this.highlight.current);
... DOM manipulations

But this feels messy and code-duplicating if not absolutely necessary. I'd much rather apply my modifications to the reference directly via the React Native API.

EDIT: More code - here's my structure and a few relevant functions to the problem. I cut out irrelevant parts to try to make the code I posted smaller

class DetailBody extends Component {
  constructor() {
    super();
}

  render() {

    return (
      <ScrollView >
        <Text>{this.props.article.intro}</Text>
        <View ref={this.props.highlight}>
          {this.props.article.json.results.map((content, index) => (
            <View key={index} style={{}}>
              {content.pinyin ? (
                <Fragment>
                  <View>
                    <Text>
                      {content.pinyin}
                    </Text>
                  </View>
                  <View>
                    <Text>
                      {content.simplified}
                    </Text>
                  </View>
                </Fragment>
              ) : (
                  <Fragment>
                    <View>
                      <Text>
                      </Text>
                    </View>
                    <View>
                      <Text>
                        {content.characters}
                      </Text>
                    </View>
                  </Fragment>
                )
              }

            </View>
          ))}
        </View>
      </ScrollView>
    )
  }
}

class Detail extends Component {
  constructor() {
    super();
    this.state = {
      currentVal: 0,
    };
    this.traverseCharacters = this.traverseCharacters.bind(this)
    this.highlight = React.createRef();
  }

  async traverseCharacters(i) {

    this.highlight.current._children[i].setNativeProps({ style: { backgroundColor: "black" } });
    this.highlight.current._children[i]._children[0]._children[0].setNativeProps({ style: { color: "white" } })
    this.highlight.current._children[i]._children[1]._children[0].setNativeProps({ style: { color: "white" } })
    if (i > 0) {
      this.clearCharacters(i)
    }
  }

  render() {

    return (
        <DetailBody {...this.props} article={this.state.article} highlight={this.highlight} />
    );
  }
}
Share Improve this question edited May 13, 2020 at 20:28 Steven Matthews asked Apr 17, 2020 at 3:38 Steven MatthewsSteven Matthews 11.4k50 gold badges137 silver badges255 bronze badges 7
  • What do you mean by on the web? Can you please provide your full code? – GalAbra Commented Apr 17, 2020 at 16:43
  • I mean, the code is working in React Native for iOS and Android, but it does not work for React Native Web. I will provide more code. – Steven Matthews Commented Apr 17, 2020 at 16:44
  • @GalAbra Ok, edited and added most of my code structure. I left out irrelevant parts, but you should be able to get a pretty idea of what I am trying to do from what I posted – Steven Matthews Commented Apr 17, 2020 at 16:50
  • I am not getting any children in ref. can you provide expo demo of your problem – Muhammad Numan Commented May 12, 2020 at 21:55
  • @CecilRodriguez ? – Muhammad Numan Commented May 13, 2020 at 20:22
 |  Show 2 more ments

2 Answers 2

Reset to default 3 +300

[Edit]: Since this 'someone's work' is for class ponent, here is one of my answer using dynamic refs with a functional ponent : Dynamic refs with functional ponent. It uses a useRef() hooks to store your dynamic refs, and so they're accessible wherever you want, with a specific id.


After trying things for a moment now, I cannot find a clean way of doing what you want to do. However, there is solutions for this, as you said with the ReactDOM. Another thing that came in my mind would be to set your refs in your child and then pass it to the parent.

Here is someone doing 'dynamic' ref in a .map using the key attribute, maybe it can be of use to you : Someone's work

Now, using direct manipulation isn't a good practice, so using this isntead of ReactDOM.findDOMNode... I don't really know which is one is worse but both are messy i guess.

setNativeProps isn't available on the children element. You either need to provide a refs to the intended child elements yourself before calling setNativeProps on them

For a ref solution you could make use of ref callbacks like below and add a ref to each and every element that you wish to update dynamically

class DetailBody extends Component {

  setRef = (i, j, ref) => {
    if(this.highlight[i]) {
      this.highlight[i][j] = ref;
    } else {
      this.highlight[i] = {[j]: ref};
    }
  }
  render() {

    return (
      <ScrollView >
        <Text>{this.props.article.intro}</Text>
        <View>
          {this.props.article.json.results.map((content, index) => (
            <View key={index} style={{}} ref= {(ref) => this.setRef(index, 'root', ref)}>
              {content.pinyin ? (
                <Fragment>
                  <View ref= {(ref) => this.setRef(index, 0, ref)}>
                    <Text>
                      {content.pinyin}
                    </Text>
                  </View>
                  <View ref= {(ref) => this.setRef(index, 1, ref)}>
                    <Text>
                      {content.simplified}
                    </Text>
                  </View>
                </Fragment>
              ) : (
                  <Fragment>
                    <View ref= {(ref) => this.setRef(index, 0, ref)}>
                      <Text>
                      </Text>
                    </View>
                    <View ref= {(ref) => this.setRef(index, 1, ref)}>
                      <Text>
                        {content.characters}
                      </Text>
                    </View>
                  </Fragment>
                )
              }

            </View>
          ))}
        </View>
      </ScrollView>
    )
  }
}

class Detail extends Component {
  constructor() {
    super();
    this.state = {
      currentVal: 0,
    };
    this.traverseCharacters = this.traverseCharacters.bind(this)
    this.highlight = {};
  }

  async traverseCharacters(i) {

    this.highlight[i].root.setNativeProps({ style: { backgroundColor: "black" } });
    this.highlight[i][0].setNativeProps({ style: { color: "white" } })
    this.highlight[i][1].setNativeProps({ style: { color: "white" } })
  }

  render() {

    return (
        <DetailBody {...this.props} article={this.state.article} highlight={this.highlight} />
    );
  }
}

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745283933a4620446.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信