Repository navigation
Closed
Labels
BugStaleThere has been a lack of activity on this issue and it may be closed soon.There has been a lack of activity on this issue and it may be closed soon.
Description
Environment
React Native Environment Info:
System:
OS: macOS 10.14.1
CPU: (8) x64 Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz
Memory: 123.34 MB / 16.00 GB
Shell: 5.3 - /bin/zsh
Binaries:
Node: 8.11.3 - /usr/local/bin/node
Yarn: 1.10.1 - ~/.yarn/bin/yarn
npm: 5.6.0 - ~/n/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 12.1, macOS 10.14, tvOS 12.1, watchOS 5.1
Android SDK:
API Levels: 23, 24, 26, 27, 28
Build Tools: 23.0.1, 26.0.2, 26.0.3, 27.0.3, 28.0.0, 28.0.0, 28.0.1, 28.0.2, 28.0.3
System Images: android-27 | Google Play Intel x86 Atom
IDEs:
Xcode: 10.1/10B61 - /usr/bin/xcodebuild
npmPackages:
react: 16.6.3 => 16.6.3
react-native: 0.57.8 => 0.57.8
npmGlobalPackages:
create-react-native-app: 1.0.0
generator-module-react-native: 0.0.2
react-native-cli: 2.0.1
react-native-create-bridge: 1.2.1
react-native-create-library: 3.1.2
react-native-git-upgrade: 0.2.7
Description
setNativeProps does not work with text property on Text component.
Reproducible Demo
See this repo:
https://github.com/tychota/bugSetNativePropsText
Expected:
- first print "-" then goes from 0 to 100 in 2 seconds
Real life:
- prints "-" on 🍎 (ios), then does nothing
- prints "-" on 🤖 (android), then does nothing
People to CC
Cause hypothesis
AFAIK:
- there is two component involved in rendering a text: a
RCTTextand aRCTRawText - while most of the properties are handled by the
RCTText(eg opacity, color, ect), the text itself is handled byRCTRawText - there is no property in the
RCTText(or its parentRCTBaseText) to set text
Next steps
I'm willing to contribute.
I think we can do something similar to 2307ea6.
Not sure exactly how to get the text since the information must be in attributed string and I would like to keep having one single source of True (hence not duplicating text and adding it as property like previous commit).
Reacted by Lucas Carvalho, TomasB, malacca and lapto
Metadata
Metadata
Assignees
Labels
BugStaleThere has been a lack of activity on this issue and it may be closed soon.There has been a lack of activity on this issue and it may be closed soon.
Activity
tychota commentedon Jan 3, 2019
makes it works on iOS, provided the props is send in form of string, eg:
If I forget the
toString, I get:Questions:
Next, Android :)
tychota commentedon Jan 3, 2019
For Android this seems to work:
tychota commentedon Jan 3, 2019
If the approach is OK, let me know, I will create a PR for further discussion.
If I don't answer ping me on Twitter (Github notification are hard to grasp): @tychota.
shergin commentedon Jan 3, 2019
@tychota Thank you for working on this! 👍
Your approach is okay, but we can improve this a bit more.
So, the output of def should be "abcdef". Actually, we probably want to make a case where both the property and nested content are not empty illegal. Adam put a lot of consideration into this topic, so I defer this decision to him. cc @rigdern
And maybe we want to go with "value" instead of "text". Adam, IIRC we discussed this as well, what do you think?
rigdern commentedon Jan 3, 2019
The problem I worked on is different but close enough that I have an opinion here.
I would say that it's not a bug that
setNativePropsdoesn't work on thetextprop of aTextcomponent. TheTextcomponent doesn't have atextprop. In addition tosetNativePropsnot doing anything, code like<Text text='foo' />doesn't do anything. The way to render text is to pass it as children to theTextcomponent:<Text>foo</Text>.I just wanted to clarify that I consider our discussion here to be about a new feature rather than a bug fix.
Adding this new feature will introduce some complexity to the
Textcomponent:Textcomponent (e.g.<Text value='foo' />) and passing text as children to theTextcomponent (e.g.<Text>foo</Text>). Today, developers don't have to give this any thought because the latter is the only option.Textas both a prop and as children (e.g.<Text value='foo'>bar</Text>). What would a developer expect to happen? Should there be a runtime error? Should one take priority over the other? Should we render them both?setNativeProps. Example:<Text>bar</Text>and later they dosetNativeProps({ value: 'foo' }). We have to consider that our solution to (2) will also determine the behavior of (3).@tychota can you describe the real world scenario you are trying to solve and why passing the text as children to the
Textcomponent isn't sufficient? Before we decide to add this feature, I want to make sure the benefits we'll get from it are worth the costs (some of which I listed above).API Feedback
If we decide to go forward with this feature, here are some thoughts on the API:
valueinstead oftextto matchTextInput'sAPI. I know thatRCTRawTextuses the prop nametextbut I think thatRCTRawTextis an implementation detail and isn't part of React Native's public API.Text, I think we should copyTextInput'sbehavior. Unfortunately,TextInputdoes different things depending on the code path you take:valueprop.For
Text, I suppose we could do (i) for all code paths but we'll still need to do (ii) in case this happens in a release build where there are no asserts.Adam Comella
Microsoft Corp.
tychota commentedon Jan 4, 2019
Real Word scenario
Fair point.
We actually discussed it with @shergin but offline.
The use case is performance, exactly in the case of what is put on the page https://facebook.github.io/react-native/docs/direct-manipulation
Two examples in my current app:
In both case the performance is slugish. To give you an example with code:
Progress (example 2)
1. Unoptimized version
click to see the code ...
The perf was horrible (drop around 15 fps in debug) still super slugish on release, even on good device (iphoneX and pixel).
2. Animated svg
click to see the code ...
We upgraded
rn-svgand last version support native driver.Perf is way better but still not ok, especially, the text finish animating later than svg
3. Trick, using Textinput
click to see the code ...
Consistant frame rate on JS and native thread, max drop to 53fps, super fluid even on low device (galaxy s3).
But using text input is super hacky.
Slider (example 1)
The slider is even worth, user side of view. Since user do a gesture, animation as not only to be fluid but be also in sync. That is impossible to do without nativeDriver (or @kmagiera reanimated).
You have an example here : https://blog.bam.tech/developper-news/create-vertical-slider-with-react-native-panresponder
While the animation is cool it does not feel native.
Is the example clearer, @rigdern ?
Do you think it is worth the effort ?
tychota commentedon Jan 4, 2019
Solutions comparison
Solution 1: props
valueortextDescription, POC: see above
Note: in comparison to what you said, text seems to work see:
https://github.com/facebook/react-native/blob/7de2f77d20b600ba30856d75660357ce7577f9ca/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m#L105-L118
Pro/cons:
Solution 2:
textRef.setNativeRefDescription
In react Instance, we add
setNativeTextand connect it only when the ref is type of Text (no sure how to do).That will allow us to do something like this:
POC
UIManager.updateNestedViewis a new method that loop under the subviews to find matching component.Pro/cons:
setNativeTextinstyled.TextUIManager.updateNestedView(parentHandle, childrenClass, props)because it can be used in other cases where a component have an implementation in two native components)Solution 3: animate string property
PR: #18187 (long awaited by community 😍)
Description
This allow us to do this:
Pro/cons:
Solution 4: reanimated, and react-native-gesture-handler
by @kmagiera
Pro/cons:
tychota commentedon Jan 4, 2019
@rigdern and @shergin: what do you think ? My recommendation is to do 2 and 3, and edit doc to point to 4.
@shergin you had concern with 2, what are they ?
Should I involve other people to the decision ?
rigdern commentedon Jan 5, 2019
@tychota thanks for your detailed posts. Understanding the real world problem you are encountering is very helpful.
Reading thru your two examples, I think you are talking about several different problems:
Textvalue.Textvalue animation in sync with another animation (e.g. SVG) or a user gesture (e.g. slider).For example in "Progress (example 2) -- 2. Animated svg", you mentioned that upgrading
rn-svgimproved the performance. I suspect that the improvement is all due to (3).I think this GitHub issue should focus on (1) and (2).
Let's talk about what an ideal API might look like. Once that's decided, we can see how to implement it.
If your problem is all about animating the value of
Text, then we'll want to integrate withAnimated. Something like this (you mentioned this under "Solution 3: animate string property"):(assume that
animatedValueis of typeAnimated.Valueor something similar in the examples below)Potential Problem: Are
Animated.Valuessupported as children anywhere in React Native? If not, this option won't work.Limitation: You can only pass a string to the
Text. Inline images/views and formatting of subsets ofTextvia nestedTextare not supported. Is this limitation acceptable?@tychota Do you see any problems with the above 2 APIs for solving your problems (let's ignore the implementation details of these APIs for now)? Am I correct in assuming that ideally you want to update the value of the
TextviaAnimatedvalues for both of your scenarios?Potential App-Level Workaround
@tychota Here's a workaround that might work for you today.
The idea is that the
ImperativeTextcomponent below minimizes the amount of work that must be done to update theTextvalue. When you want to update theTextvalue, instead of dirtying and rerendering all ofCircleProgressionor whatever, justImperativeTextgets dirtied and needs to rerender.I haven't tested this so I don't know if it's fast enough for your scenario.
Note that I modeled
ImperativeTextafter the Fully uncontrolled component with akeypattern to avoid the gotchas described in that blog post.Thoughts on @tychota's Solutions
Solution 1: props
valueortextI suspect that this solution will facilitate a developer passing an
Animated.Valueto thevalue/textprop. I really like this aspect. The downsides were covered in my earlier comment.Solution 2:
textRef.setNativeTextUnlike "Solution 1", I suspect that this solution won't help us update the
Text'svalue via anAnimatedvalue (becauseAnimatedleveragessetNativePropsand doesn't know aboutsetNativeText). This seems like a big downside.Solution 3: animate string property (aka PR #18187)
Are you sure that PR #18187 alone will enable code like
<Text>{this.state.animatedPercentage}</Text>to work? Earlier in this comment, I questioned whetherAnimated.Valuesare supported in component children.Solution 4: reanimated, and react-native-gesture-handler
Do these libraries provide a good solution for animating the content of a
Textcomponent?rigdern commentedon Jan 5, 2019
I see. The prop is called
valueon the JavaScriptTextInputcomponent but it's calledtexton the native components that backTextInput.I wonder if this causes problems if you try to pass an
Animatedvalue to thevalueprop becauseAnimatedmight try to callsetNativePropsonvaluerather thantextbecausevalueis the name of the prop associated with theAnimatedvalue.tychota commentedon Jan 7, 2019
Sorry not putting that earlier on.
I think I have a slightly different classification of the problem. By order of importance
User problems:
Dev experience:
props = f(time)where f can be easing or interpolation)setNativePropssometimes works, sometimes don't and there is no clue about what works, what don't and what are the limitationThose UX problems and DX problems translate into a few technical problems:
Animatedin a fast manner that stay in sync (2) compared to other animation and without noticeable performance drop (1)Thus we should focus on (1) (2) and (4), in my opinion.
I think it works (for me children is only syntactic sugar for children props) but let me test. If it does not, we should make it works.
I will try in my Minimal working example.
I think this works:
was it what you meant ?
Sadly it is not enough in both the animated Text (slugish in bad android) and the pan responder slider (not feeling native, even in iPhone X)
Solution 2: seems good concern so I dislike solution 2 a bit more. Plus it require another api to update a props.
Solution 3: not sure but I can easily (or not) patch the minimal working example here (https://github.com/tychota/bugSetNativePropsText) and see. I will try later this week and report here.
Solution 4: reanimated, and react-native-gesture-handler
I think not, good catch: https://github.com/kmagiera/react-native-reanimated/blob/master/src/ConfigHelper.js#L31-L104 :) I will point @kmagiera on this issue and see but I guess for it to support, we should do "solution 1" anyway.
rigdern commentedon Jan 7, 2019
I agree with focusing on (1) and (2) in this issue because they are both
Textrelated. If you want to discuss (4) (Frame rate of user interacting with a slider), can you create a different GitHub issue for it? I think it's worth discussing independently in another issue rather than entangling it with theTextconversation here.Great! I look forward to hearing about the result of your experiment.
No. I was trying to convey two different API options for using
Animatedvalues to control theTextcontent and describe the potential limitations of each option. The options wereAnimatedvalue as children (<Text>{animatedValue}</Text>) andAnimatedvalue as a prop (<Text value={animatedValue} />). Only the latter (as a prop) has the limitation that you can't use inline images/views or format subsets ofTextvia nestedText. Hopefully that clears up what I meant.alloy commentedon Mar 19, 2019
Hello there 👋 this issue seems to have stalled [after some good back and forth!]. I’ll label it as needing Follow Up, meaning that it will get closed in the future after further stagnation.
tychota commentedon Mar 19, 2019
Thanks for pinging @alloy, completly forgotten this. You could have closen "stale" it but you chose to ping and that is motivating me to finish that. Thank you :)
Summary
To sum stuff up:
setNativePropsdoes not work withtextproperty onTextcomponent #22855 (comment) describes potential solutions: I have 1) working in my project (patch packaged)setNativePropsdoes not work withtextproperty onTextcomponent #22855 (comment) are they show stopper ?I should test react native Text update for solution 3 but i guess it depends on solution 1 and also #18187 (one year old, @alloy can you ping there tooo so it get merged).
Maybe someone on rn team have more insight on animated api and how it works and can answer or explain me.
Next steps
Before going i would like an approval of the choice of going for solution 1, with or without renamming value props from "text" to "value". And how to handle concerns.
Then I can PR solution 1.
Then we can look if solution 3 works out the box, or need another PR (Support Interpolation of strings when using native driver in Animated, fix Expected node to be marked as "native", optimize AnimatedNode creation and connections #18187 or one i can do) to works.
Last celebrate :)
mayconmesquita commentedon Jun 21, 2019
This feature would be awesome!! 🥇
stale commentedon Sep 19, 2019
Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.
ken0x0a commentedon Sep 19, 2019
Using react-native-reanimated to animate text doesn't work @ android.
There is a PR for that, but still not merged. 😭
stale commentedon Dec 18, 2019
Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.
stale commentedon Dec 25, 2019
Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please feel free to create a new issue with up-to-date information.