Tried to register two views with the same name ProgressBarAndroid - javascript

Using react version 16.0.0 with react-native version 0.49.1 raises the red screen error "Tried to register two views with the same name ProgressBarAndroid". Removing all imports and instances of ProgressBarAndroid results in a well functioning program. Downgrading to react-native version 0.48.4 works as well. How do I use ProgressBarAndroid with the latest React Native version?

React Native starting from version 0.49 triggers this error if you are trying to call requireNativeComponent() for same component more than once. Even if they are called from different modules.
I had similar issue with custom view MyCustomView. So I just wrapped it in a single module:
// MyCustomView.js
import {requireNativeComponent} from 'react-native'
const MyCustomView = requireNativeComponent('MyCustomView', null)
export default MyCustomView
Though it might not be your exact case the root cause is the same.

import ReactNative from 'react-native';
const description = Object.getOwnPropertyDescriptor( ReactNative, 'requireNativeComponent' )
if ( !description.writable ) {
Object.defineProperty( ReactNative, 'requireNativeComponent', {
value: (function () {
const cache = {}
const _requireNativeComponent = ReactNative.requireNativeComponent
return function requireNativeComponent( nativeComponent ) {
if ( !cache[ nativeComponent ] ) {
cache[ nativeComponent ] = _requireNativeComponent( nativeComponent )
}
return cache[ nativeComponent ]
}
})(), writable: true
} )
}

I experienced this during hot-reload in development. What causes the issue is the following: however JS is reloaded, the native code is still holding onto the same reference that it previously held onto. Whenever JS runs requireNativeComponent with the same viewName, it throws because the previous reference for the given viewName still exists. Here is the source file of requireNativeComponent, which clearly states that it should be memozied on the React Native side and only initialized once. Thus, the answer of #Teivaz is satisfying and no further hacking (like the answer of #蒋宏伟) is needed. If your code is structured well, you don't have to use any manual caching because your import structure solves it for you. :)

Related

too much render with react markdown

I am using React Markdown (https://www.npmjs.com/package/react-markdown) to render markdown content in my NextJS project.
When I refresh I have two "toto" & "titi" in my terminal... It is normal or what's wrong with this code?
import Head from 'next/head';
import ReactMarkdown from 'react-markdown';
function Section ({ data }) {
const content = JSON.parse(data.markdown);
const {
title,
sortContent
} = data;
console.log('toto');
return (
<>
<main>
<h1>{title}</h1>
<h1>{sortContent}</h1>
<ReactMarkdown source={content.default} escapeHtml={false} />
</main>
</>
)
}
export async function getServerSideProps (context) {
const json = await import('../../content/article1/data.json');
const content = await import('../../content/fr/article1/content.md');
console.log('titi');
return {
props: {
data: {
title: json.title_content,
sortContent: json.short_content,
markdown: JSON.stringify(content)
}
}
}
}
export default Section
It's part of Reacts development tooling, StrictMode. It is expected and only applies in development mode. You can remove the StrictMode to see it only render the expected number of times, but obviously you lose some development tooling. This tooling can warn you about certain unsafe or unwise practices you might want to avoid such as using legacy APIs.
More details here:
Reactjs Docs
A blog with a good overview
If this is truly the only code you have, then it looks like it's normal. You may have other code that uses these components and that's why in shows twice. But based off the code you have right there, there's no bug.
This is a known side-effect of using React.StrictMode, only in debug mode. You can read more about this here.
Strict mode can’t automatically detect side effects for you, but it
can help you spot them by making them a little more deterministic.
This is done by intentionally double-invoking the following functions:
Class component constructor, render, and shouldComponentUpdate methods
Class component static getDerivedStateFromProps method
Function component bodies
State updater functions (the first argument to setState) Functions passed to useState, useMemo, or useReducer

Next.js: How to dynamically import external client-side only React components into Server-Side-Rendering apps developed?

I know this question has been asked multiple times before but none of the solution seems to work.
I'm trying to use the library 'react-chat-popup' which only renders on client side in a SSR app.(built using next.js framework) The normal way to use this library is to call import {Chat} from 'react-chat-popup' and then render it directly as <Chat/>.
The solution I have found for SSR apps is to check if typedef of window !=== 'undefined' in the componentDidMount method before dynamically importing the library as importing the library normally alone would already cause the window is not defined error. So I found the link https://github.com/zeit/next.js/issues/2940 which suggested the following:
Chat = dynamic(import('react-chat-popup').then(m => {
const {Foo} = m;
Foo.__webpackChunkName = m.__webpackChunkName;
return Foo;
}));
However, my foo object becomes null when I do this. When I print out the m object in the callback, i get {"__webpackChunkName":"react_chat_popup_6445a148970fe64a2d707d15c41abb03"} How do I properly import the library and start using the <Chat/> element in this case?
Next js now has its own way of doing dynamic imports with no SSR.
import dynamic from 'next/dynamic'
const DynamicComponentWithNoSSR = dynamic(
() => import('../components/hello3'),
{ ssr: false }
)
Here is the link of their docs: next js
I've managed to resolve this by first declaring a variable at the top:
let Chat = ''
then doing the import this way in componentDidMount:
async componentDidMount(){
let result = await import('react-chat-popup')
Chat = result.Chat
this.setState({
appIsMounted: true
})
}
and finally render it like this:
<NoSSR>
{this.state.appIsMounted? <Chat/> : null}
</NoSSR>
You may not always want to include a module on server-side. For
example, when the module includes a library that only works in the
browser.
Import the library normally in child component and import that component dynamically on parent component.
https://nextjs.org/docs/advanced-features/dynamic-import#with-no-ssr
This approach worked for me.

React: How to add new value to props from imported file?

I am (very) new to React and have been given the task of adding some data to a component that's being brought in from another file. This file spits out some JSON and I want to access certain pieces of data from it, for example:
config.forms.enquiry.title
I am importing the file fine - no problems there. But I am not sure how to include config into my props.
I found a working example, in another file, and have copied what it does. My code is as such
Brings in file with JSON:
import { withSettings } from 'services/settingsFile';
Add config in render function:
render () {
const styles = getStyles(this.props, this.context, this.state);
const { config } = this.props;
// other stuff
Add to propTypes:
enquiryForm.propTypes = {
config: PropTypes.object.isRequired,
// other stuff
Add to compose:
export const enquiryForm = compose(
withSettings,
// other stuff
However, I get the error:
Failed context type: The context config is marked as required in
n, but its value is undefined.
And from here I am not sure what to do. I know it's a tough question, but I know very little about React and have been thrown in the deep end.
Would anyone know what/where I should be searching for to fix this?
If you can import it like,
import { withSettings } from 'services/settingsFile';
why dont you use it like,
const { config } = withSettings;
OK, so the issue was that there was no wrapping element setting config as am attribute.
I had to go up a level to where my component was being brought in and wrap:
<SettingsFile config={window.settingsFile}>
around:
<Component conf={config} />
Then, the component I was working on was able to read config.

Debugging why react-native release build crushes and debug one works fine

I was working in Debug mode where everything seemed fine, however when I build my app to TestFlight (i.e. release build) it crashed at LaunchScreen.
After some time and debugging I narrowed issue down to following code
import React from 'react'
import { Subscribe } from 'unstated'
const getStoreAsProps = (storeArr) => {
const storeProps = {}
storeArr.map(value => (storeProps[value.constructor.name] = value))
return storeProps
}
const withStore = (...args) => (Element) => () => (
<Subscribe to={[...args]}>{(...args) => <Element {...getStoreAsProps(args)} />}</Subscribe>
)
export default withStore
The way this works is as follows
import React from "react"
import { Text } from "react-native"
import AuthStore from "./store/Auth"
import RouterStore from "./store/Router"
import withStore from "./store"
class MyComponent extends React.Component {
render() {
const {AuthStore, RouterStore} = this.props
return <Text>{AuthStore.state.username} {RouterStore.state.pathname}</Text>
}
}
export default withStore(AuthStore, RouterStore)(MyComponent)
So essentially withStore is a higher order component that can take in any number of arguments, in this case Stores and pass them to Subscribe component (this is part of state management library I am using called unstaded) which in turn returns render props that are then passed to my component as props.
It works fine in Debug mode, but I get error like this in Release mode
undefined is not an object while evaluating e.state
This error from XCode debug logs.
I think something somewhere during Release build is different compared to Debug one that makes this.props.AuthState for example [undefined] and error is thrown when I am specifying <Text>{AuthStore.state.username} {RouterStore.state.pathname}</Text> where my Store props are undefined, hence I can't access their state.
I'd love to keep this Higher Order Component I made for store, as it enables really nice dev experience, but need to be able to debug what exactly breaks in release build, which thus far I was not able to do.
What optimisations are made during release build that could have effect here?
Answer originates from: https://github.com/facebook/metro/issues/182#issuecomment-398052619
Issue was in accessing value.constructor.name where I was assuming it will always be the same as my Container name. During minification these change, hence it was undefined, adding unique identifier to a class resolves the issue

Code Splitting React components

Im relatively new to React (i'm using preact.js, to be precise) and i am trying to code split out react components using webpack 2.
Im exporting my component as stated in the documentation and i am then importing it on load.
import('./components/List').then((List) => {
render(<List />, document.getElementById('main'));
});
The script loads but i'm not handling the promise callback correctly and finding it hard to see any documentation that shows a working version.
List returns the following object:
I saw your repo. It looks like that your list component doesn't have a export default.
I would add the default and inside your then, when you handle the promise, I'd do it in this way
.then(module => {
const Component = module.default;
render(<Component />, document.getElementById('main'))
})

Categories