How to inject JavaScript in React Native? - javascript

I am developing a react native app. I am super confused that how to inject javascript code in react native. Though I am struggling somehow to work with react native but the thing is sometimes I need to inject some javascript code in my react native or say the homescreen.js type files, but I somehow end up into a syntax error. For example:
I am trying to implement this in a stylesheet.
const styles = Stylesheet.create({
//some styles
viewStyle:{
Platform.select({
ios:{
marginTop:2,
},
android:{
marginTop:3
}
});
}
//some styles
});
But it just does not work! it doesn't work even when I apply ...Platform instead of Platform.
**Note: I have import {Platform} from 'react-native'
My version is 0.57.something, but what I want to know is what is the syntax to implement javascript in these files. Just like for example in PHP we have the following:
<?php
//your logic
for(something){
?>
<View></View>
<?php
}
?>
Similarly for other languages we have something like the <% %>, {{ }} tags but what should I use in React Native. I always end up with a syntax error.
So my questions are, can anyone help me understand what the restriction is within React Native and where I can use and should not use tags? And if tags are available what are they?
I am super confused and was unable to find a similar question like this anywhere on Stack Overflow. I'd appreciate anyone's inputs, the more answers the more it will be helpful.

So I'm not sure what kind of structure you have set up but I'm going to assume you have a single file (lets call it homescreen.js) and you want to define styles for a component. I'm assuming you have already imported everything that's necessary (StyleSheet, Platform, View and Text from react-native, and the default export React from react).
So first, let's make the stylesheet. You almost have it correct above, you need the following:
const styles = Stylesheet.create({
viewStyle: Platform.select({
ios:{
marginTop:2,
},
android:{
marginTop:3
}
})
})
(You mention above that you're getting a syntax error, this is probably due to the semicolon in your stylesheet object.)
Now we need to create the React class for your HomeScreen component. Again, not sure of the context but you should be able to pull out the bits you need.
class HomeScreen extends React.Component {
render() {
return (
<View style={styles.viewStyle}>
<Text>I should have marginTop 2 on iOS and marginTop 3 on Android.</Text>
</View>
);
}
}

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

React Martial UI component overwritten/conflicts when new component is loaded

I am talking about a big web app that has jquery and bootstrap stuff init.
Part of rewriting this giant app using react and material UI, we are writing component by component. Things work fine in general as we make progress toward making this a react app soon.
Our problem:
When a new react component is loaded into the page, the existing (already loaded) react components will lose some or all styles.
We checked the new component load new style (classes) which are matching the names of existing classes for other already loaded components.
Ex:
As you can see, jss1, jss2, ... MuiCardHeader, MuiGrid, ... were also the names for the previously loaded components and now they are overwritten for the newly loaded component.
Packages.json:
webpack config:
Some component code: we are using make style and in some cases withstyle
Tried too much stuff. But nothing seems to work. On initial load, the map has all the correct material-ui stuff but as soon as I click on a marker and the popup component loads in. Now the map is messed up as some styles are overwritten.
How can we make it so that each component styles are named unique and never conflicts with other stuff?
I checked MUI docs and GitHub issues about kinda similar issue but nothing is working for us.
Any thoughts?
If I add:
import { StylesProvider, createGenerateClassName } from '#material-ui/core/styles';
const generateClassName1 = createGenerateClassName({
seed: 'App2',
});
my custom classes ( like root, mydivstyle) will have the prefix like app2-jss1-root, app2-jss2-mydivstyle, ...
but muiCard, MuiCardHeader, ... still being overwritten.
So after a few trial and error. I was able to solve this.
Basically we don't have a component tree path where you can could add a single class generator because of our app structure at this stage. We will soon have one.
The solution was to wrap every component like.
import { StylesProvider, createGenerateClassName } from '#material-ui/core/styles';
const generateClassName = createGenerateClassName({
seed: 'anyprefix',
});
class ActivityContainer extends Component {
render() {
return (
<StylesProvider generateClassName={generateClassName}>
<componenet/>
</StylesProvider>
);
};
}
I had to do this on the container level, this way any component loaded in that container will inherit this prefix.
No more conflicting class names between components and can load them dynamically.
Not a great way but no other option at least in our case. It will leave more classes on the DOM.

Access Office UI Fabric theme colours in JavaScript

Based upon the documentation about Usage via JavaScript styling libraries, I'm trying to access the Office Fabric UI theme colours in my application. I've followed the instructions and installed #uifabric/styling. I'm then supposed to simply import the styles as
import {
styles
} from '#uifabric/styling';
...to get access to the colours. But I get the following TypeScript error:
[ts] Module '"c:/.../node_modules/#uifabric/styling/lib/index"' has
no exported member 'styles'. Did you mean 'IStyle'?
Is the documentation old or maybe the typescript definitions are old?
Any ideas?
How the example in the documentation is supposed to work is still an enigma for me. But I managed to get getTheme() to work together with custom styles.
Here's a quick React-Typescript example of how themes can be used in Javascript, and maybe also what the documentation should be saying. A complete theme can be created with the Theme Generator
import { getTheme, loadTheme } from '#uifabric/styling';
import * as React from 'react';
loadTheme(
{
palette: {
"themePrimary": "#489958"
}
}
);
class App extends React.Component {
private theme = getTheme();
public render() {
return (
<div className="App">
<h1 style={{color: this.theme.palette.themePrimary}}>It works</h1>
</div>
);
}
}
export default App;
you definitely found a bug in our documentation. We've recently moved most of our docs over to the wiki. I'll get this cleaned up one way or another.
Here's an issue to track the work.
https://github.com/OfficeDev/office-ui-fabric-react/issues/5770

react JS how to make theme-able component

I am trying to decide the best route to go for distributing a component that others can theme. They may need to change the html structure as well as the css/bootstrap styling. (I am using react-bootstrap with the component.
The only way I can see to do this is to make a component folder with all of the subcomponents in src/themes/default, src/themes/awesome, etc and then import them into the main component which people can then call by doing something like this...
This is just a concept, it probably isn't completely valid
import default from './themes/default/index.js`
import awesome from './themes/awesome/index.js`
const themes = {
default,
aweosme,
}
const MyComponent = ({ theme, otherprop }) => {
return (
<themes.default otherprop={otherprop} />
)
}
then if someone wanted to contribute a theme, they would have to write a whole component complete with html structure in the jsx and inline styles to go along with it. It would require them to be familiar with react, but I cannot see another way to do it unless I have missed something...
What do you think?

React Server side rendering with Express - warning on the client checksum & Styling

I am new to React server side rendering , working on a small demo with React , Redux , React router , Material UI. The problem I am facing is the below warning. Unsure how the isomorphic styling and assets works with webpack.
I understood the pipeline how server side rendering work , please correct me if it is wrong.
Using renderToString the React component get resolved to the HTML.
Once the HTML renders on the client side , all the events , styling gets attached meaning react try to render the component on the client side again , if the component is already created it will create it again.
If the component is already created or NOT is derived based on the Checksum.
Issue reported in GIT
https://github.com/callemall/material-ui/issues/4466
Code
https://github.com/sabha/React-Redux-Router-MaterialUI-ServerSideRendering
'warning.js:44Warning: React attempted to reuse markup in a container
but the checksum was invalid. This generally means that you are using
server rendering and the markup generated on the server was not what
the client was expecting. React injected new markup to compensate
which works but you have lost many of the benefits of server
rendering. Instead, figure out why the markup being generated is
different on the client or server: (client)
0;text-align:center;mui-prepared:;-webki (server)
0;text-align:center;-webkit-user-select:'
In this Razzle Material UI Styled Example project I am setting the user agent this way:
server.js:
renderToString(<Application userAgent={request.headers['user-agent']} />)
client.js:
hydrate(<Application userAgent={navigator.userAgent} />, document.getElementById('root'))
Main.js:
class Main extends Component {
constructor(properties, context) {
super(properties, context)
this.muiTheme = getMuiTheme({
userAgent: properties.userAgent
})
}
render() {
return (
<MuiThemeProvider muiTheme={this.muiTheme}></MuiThemeProvider>
)
}
}
It works well and I think it is correct too.
Material-UI, with its inline-style approach to styling elements, has this gotcha with respect to server-side rendering:
On the client, MaterialUI rendering only adds inline styles specific to the browser that is running the app. But on the server, you aren't in a browser and so how to know which specific style rules to use so that the rendered HTML matches the client-rendered HTML and avoids the React warning?
They have documentation on how to solve the issue. Essentially it means ensuring you set the user agent string (captured from the HTTP Request Header) before doing your server side rendering.
This is from their serverside rendering documentation:
import getMuiTheme from 'material-ui/getMuiTheme';
import MuiThemeProvider from 'material-ui/MuiThemeProvider';
import {green100, green500, green700} from 'material-ui/styles/colors';
const muiTheme = getMuiTheme({
palette: {
primary1Color: green500,
primary2Color: green700,
primary3Color: green100,
},
}, {
avatar: {
borderColor: null,
},
userAgent: req.headers['user-agent'],
});
class Main extends React.Component {
render() {
return (
<MuiThemeProvider muiTheme={muiTheme}>
<div>Hello world</div>
</MuiThemeProvider>
);
}
}
(client) 0;text-align:center;mui-prepared:;-webki
(server) 0;text-align:center;-webkit-user-select:
You will notice that the difference between the two is extra mui-prepared that is not present in the server render. There is a note about this at the bottom of the server rendering guide in the docs.
In order to make sure our style transformations are only applied once, we add an additional property to each style when process.env.NODE_ENV !== 'production'.
It looks like you have process.env.NODE_ENV=production only on the server (this was the case for me).

Categories