【问题标题】:How do I access children components of a reference in React Native Web?如何在 React Native Web 中访问引用的子组件?
【发布时间】:2020-04-17 03:38:27
【问题描述】:

我在 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();

作为 props 传入子组件并按原样使用:

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

【问题讨论】:

  • 你说的在网络上是什么意思?你能提供你的完整代码吗?
  • 我的意思是,代码在适用于 iOS 和 Android 的 React Native 中运行,但不适用于 React Native Web。我会提供更多代码。
  • @GalAbra 好的,编辑并添加了我的大部分代码结构。我省略了不相关的部分,但您应该能够从我发布的内容中大致了解我正在尝试做什么
  • 我没有在参考中得到任何孩子。你能提供你的问题的展览演示吗
  • @CecilRodriguez ?

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


【解决方案1】:

[编辑]:由于这个“某人的工作”是针对类组件的,所以这是我使用带有功能组件的动态引用的答案之一:Dynamic refs with functional component。它使用useRef() 挂钩来存储您的动态引用,因此您可以在任何地方使用特定的 ID 访问它们。


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

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

现在,使用直接操作不是一个好习惯,所以使用它而不是 ReactDOM.findDOMNode...我真的不知道哪个更糟,但我猜两者都很混乱。

【讨论】:

    【解决方案2】:

    setNativeProps 在子元素上不可用。在调用 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} />
        );
      }
    }
    

    【讨论】:

    • 如果这仍然不适合您,请告诉我。我已经在没有额外嵌套映射的情况下测试了这个逻辑
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-17
    • 1970-01-01
    • 2016-10-05
    • 2017-11-12
    • 1970-01-01
    • 2020-08-31
    相关资源
    最近更新 更多