如何在React Native Web中访问引用的子组件?

时间:2020-04-17 03:38:27

标签: javascript react-native react-native-web

我在React Native Web应用程序中有一些参考-这些参考适用于React Native,但不适用于RNW。

例如,我有以下代码:

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" } })

基于哪个:

this.highlight = React.createRef();

将哪个作为道具传递给子组件,并按如下方式使用:

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

它有几个孩子(也有嵌套的孩子)。

但是,在网络上根本没有._children

我如何接待孩子?

如果Platform.OS === 'web',则可以直接进行DOM操作:

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

但是,如果不是绝对必要的话,这会带来混乱和代码重复。我宁愿直接通过React Native API将修改应用于引用。

编辑:更多代码-这是我的结构以及该问题的一些相关功能。我删去了不相关的部分,以尝试使发布的代码更小

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} />
    );
  }
}

2 个答案:

答案 0 :(得分:3)

[编辑]:由于此“某人的工作”用于类组件,因此这是我将动态引用与功能组件:Dynamic refs with functional component一起使用的答案之一。它使用useRef()钩子来存储动态引用,因此可以使用特定的ID在任意位置访问它们。


尝试了一会儿之后,我找不到一种干净的方法来做自己想做的事情。但是,正如您使用ReactDOM所说的那样,有解决方案。我想到的另一件事是在您的孩子中放置您的裁判,然后将其传递给父母。

有人在其中使用key属性在.map中进行“动态”引用,也许对您有用:Someone's work

现在,使用直接操作不是一个好习惯,因此使用ReactDOM.findDOMNode的这个方法……我真的不知道哪一个更糟,但是我都觉得这很混乱。

答案 1 :(得分:1)

setNativeProps在children元素上不可用。在调用setNativeProps之前,您要么需要自己提供对预期子元素的引用

对于 ref解决方案,您可以使用如下所示的 ref回调,并向要动态更新的每个元素添加一个ref

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} />
    );
  }
}
相关问题