Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

My React component does not update in the Safari browser

Thought everything was going great. Works perfectly in Chrome, FF, Edge, even IE 11!

The parent component holds all the sate. I pass the bets object to the child component which calculates a count to pass to the grandchild component to display.

The parent state 'bets' is an object with the keys as an ID and the value as an object.

The parent state is correctly changing when I interact with the app. Why will only Safari not update when the parent state changes? (on iOS and MacOS)

Parent

class ParentComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            bets: {}
        };
    }
}

Child

getBadgeCount = (league) => {
    const bets = this.props.bets;
    let count = 0;
    Object.keys(bets).map((bet) => bets[bet].event.league === league && count++);
    return count;
};

// ...

<ChildItem count={this.getBadgeCount(league)} />

GrandChild

class GrandChildComponent extends React.Component {
    render() {
        const { count } = this.props;
        return (
            <div>
                <div>
                    {count > 0 && <div>{count}</div>}
                </div>
            </div>
        );
    }
}

I console.log the count inside the grandchild render and in the componentDidUpdate and it shows the right number. Is there something apple/safari specific with react I am missing?

like image 663
Taylor A. Leach Avatar asked Mar 05 '19 17:03

Taylor A. Leach


People also ask

Why doesn’t my React component change when I change the URL?

The address bar in your browser updates to your new URL, the your component doesn’t change – and stubbornly remains glued to the screen. This a common case for many React developers who have a potentially troublesome combination of: Not using a route component – i.e. component= {ReactComponent} Fortunately though, there’s an easy fix.

How do I reload the react app in browser?

Reload the app on browser Ctrl + R. Confirm that all changes are now reflected on the browser. I have been learning React for the past few weeks and usually each tutorial started by following commands ... and all the components were usually created inside index.js.

What is the usecontext provider in react?

The Context Provider is meant to wrap your consumer components with it so that the context will be made available to all components wrapped by it. First we have a Card component that renders our card component containing our counter and buttons to increment and decrement it. The useContext call brings in AppContext into this component.

How to update React components with new data from Redux?

When Redux cannot see that the state has changed, it will not update the React components with new data from the state. The way to “tell” Redux that the state has changed is to create a new object - which will have a new reference. We do that by cloning the old state, and adding our changes on top of the new object.


3 Answers

In the case where there are variables being changed based on which you can switch between the styles (opacity: 1 or opacity: 0.99) You can try adding a key to the element which is not being updated in Safari/iOS.

<div key={new Date()} className={'myComponent'}>{Count}</div>

I ran into the same problem, this seems to work for now.

like image 83
Shivang Bhandari Avatar answered Nov 15 '22 02:11

Shivang Bhandari


So I did solve the very bizarre issue after a few days.

What was happening was I guess the engine in the Safari browser was not re-rendering the little badge icon correctly. I would print out the value inside the DOM, OUTSIDE of the styled badge I was using, and the number would update as expected... Leading me to believe the issue was related to styles.

THEN after removing what I thought was the CSS causing the issue, I noticed that it looked like safari was 'partially' updating the value in the badge. It appears to have half re-rendered, and the previous number collides with the new value... Not sure if this is some obscure problem with the render engine?

enter image description here

After adding and removing all the CSS one by one, the issue remained so I decided to trick the browser to 'force' render with a simple calculation inside the grandchild where it was being rendered:

const safariRenderHack = { opacity: count % 2 ? 1 : 0.99 };

<div style={safariRenderHack}>{count}</div>

enter image description here

Not a great solution but oh well I guess it's fixed. ha

like image 33
Taylor A. Leach Avatar answered Nov 15 '22 03:11

Taylor A. Leach


I just run into similar problem. Safari didn't re-render some texts implemented as:

<span>{someValue}</span>

On 'someValue' field update, reactJS worked fine (element was requested to render) but Safari re-renders only area of new value (shorter than previous). UI glitches :-/

If I done anything to CSS via Developer tools, element has been rendered again and looks fine :-/

After some tries, I luckily used a 'display: block;' style property and it starts to re-rendering absolutely fine. Also 'display: inline-block;' will fix that problem too, if it is needed to be used.

like image 32
zegee29 Avatar answered Nov 15 '22 03:11

zegee29