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 component 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} />
);
}
}
Creating Refs Refs are created using React. createRef() and attached to React elements via the ref attribute. Accessing Refs When we assign a ref to an element or child component in the render, then we can access the element using the current attribute of the ref. const element = this.
In React's JSX, a component with children is always identified by an opening tag and a closing tag. Each child must be placed between these two tags, just as we have seen above.
If a component, when used, contains child components or React nodes inside of the component (e.g., <Parent><Child /></Parent> or <Parent><span>test<span></Parent> ) these React node or component instances can be accessed by using this. props. children .
[Edit]: Since this 'someone's work' is for class component, here is one of my answer using dynamic refs with a functional component : Dynamic refs with functional component. 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With