Background with two colors - React Native - react-native

Is there a way to have a background with two colors as follows: Two colors
I tried expos Linear Gradient, but that's Gradient. I'm not sure how to put two colors in the main View tag as background ?
Any suggestions?

If the dimensions of the view doesn't get you anywhere, try to manipulate its borders, for example, try this code:
import React, { Component } from 'react'
import { View, Dimensions } from 'react-native'
const { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } = Dimensions.get('window')
class App extends Component {
render() {
return (
<View style={{ flex: 1 }}>
<View
width: SCREEN_WIDTH,
height: 0,
borderTopColor: "blue",
borderTopWidth: SCREEN_HEIGHT / 2,
borderRightWidth: SCREEN_WIDTH,
borderRightColor: 'transparent'
/>
</View>
)
}
}
export default App
And it gives you:
Off Topic
I still don't understand why people dislike questions like this. Yes there's no code posted, but it doesn't mean he didn't try anything. Maybe he did, but none of the methods he tried was anywhere near the answer, then why should he post the code up here to make the question lengthy, just to prove that he did try? And, even if he didn't try much, maybe it's because he had no clue what to try, isn't that a possibility?
There are many questions without any code posted but got hundreds of upvotes, such as "How to remove an element from an array in JavaScript?". Really? I honestly think if you even read the documentation and tried some methods such as .splice, .reduce, .unshift, you would've figured that out without having to ask it here on SO. Those questions were popular because they made a lot of beginners (including me) lives easier, not because those questions showed that whoever asked it made a great amount of effort. And this question certainly is a good one in that sense. (But maybe he should change the title of the question to make it more specific, because it would benefit others when they goole it)

Related

How to virtualize a FlatList inside FlatList (RN Web)?

How do I convince a vertical React Native FlatList to virtualize correctly inside another vertical (non-virtualizing) FlatList, in React Native Web?
So far, it seems that by default, scrolling to a certain point or responsive resize re-renderings tend to cause the virtualization to go haywire. This Snack demonstrates the problem. Be sure you're on the "Web" tab as the device builds seem to work correctly. Here's a repro through codesandbox too.
Update: Per request, here's the code inline as well. This is a full program that can paste into, say, a new expo init project (or similar) to see the strange behavior and experiment with it.
import React, { useCallback } from 'react';
import { FlatList, Text, useWindowDimensions, View } from 'react-native';
// Make 200 rows for the big list (which will draw green and red with some info).
const bigListData = Array(200).fill(0).map((element, index) => index);
function onViewableChange({ viewableItems }) {
if (viewableItems.length < 2) {
console.log(`VIEWABLE CHANGE! Only ${viewableItems.length} visible...`);
} else {
console.log(`VIEWABLE CHANGE! ${viewableItems[0].index} to ${viewableItems[viewableItems.length - 1].index}`);
}
}
function BigList() {
const { height, width } = useWindowDimensions();
const betweenRows = 10;
const itemHeight = height / 8;
const totalRowHeight = itemHeight + betweenRows;
const renderer = useCallback(({ item }) => {
const key = `i_${item}`;
return <View key={key} style={{
backgroundColor: item % 2 ? "red" : "green",
height: itemHeight,
width: '90%',
marginLeft: '5%',
marginBottom: betweenRows }}>
<Text>{key}, rh: {totalRowHeight}, offset: {totalRowHeight * item}, i {item}</Text>
</View>;
}, [itemHeight, totalRowHeight]);
const getItemLayout = useCallback((__data, index) => ({
index,
length: itemHeight,
offset: index * totalRowHeight
}), [itemHeight, totalRowHeight]);
return <FlatList
data={bigListData}
getItemLayout={getItemLayout}
key={'flatList'}
numColumns={1}
onViewableItemsChanged={onViewableChange}
renderItem={renderer}
/>;
}
function NoNestedFlatLists() {
const windowHeight = useWindowDimensions().height;
return <View style={{ height: windowHeight, width: '80%' }}><BigList /></View>;
}
function renderComponent({ item }) {
if (item.type === "widget") {
// Using height 600 here, but assume we cannot easily predict this height (due to text wrappings).
return <View key={item.type} style={{ backgroundColor: 'blue', height: 600, width: '100%', marginBottom: 15 }} />
}
return <BigList key={item.type} />;
}
function NestedFlatLists() {
const windowHeight = useWindowDimensions().height;
const components = [{ type: "widget" }, { type: "bigList" }];
return <FlatList
data={components}
key={'dynamicAppFlatList'}
numColumns={1}
renderItem={renderComponent}
style={{ height: windowHeight, width: '80%' }}
/>;
}
export default function App() {
const windowHeight = useWindowDimensions().height;
// Rendering just the following has no virtualization issues.
// The viewable change events make sense, no items suddenly disappear, no complete app meltdown...
//return <NoNestedFlatLists />;
// However:
// Any useful dynamic "rows of components" architecture melts down when virtualization comes into play.
// This sample represents such an app whose feeds have asked the app to render a "widget" followed by a
// "bigList" who could well have a few hundred items itself and thus really needs virtualization to work
// well on low-end devices. This demo leans on console logs. In snack.expo.dev, at time of writing, these
// feel hidden: Click the footer bar, either on the checkmark or an empty space, and then the "Logs" tab.
// Once you scroll down about half way in the "App", even slowly, you'll get logs like the following:
// Chrome: VIEWABLE CHANGE! 83 to 90
// Chrome: VIEWABLE CHANGE! 85 to 92
// Chrome: VIEWABLE CHANGE! Only 0 visible...
// Chrome: VIEWABLE CHANGE! 176 to 183
// Chrome: VIEWABLE CHANGE! 177 to 184
// At which time, all the UI disappears. What it thinks is viewable is quite wrong. Try to scroll around,
// but none of the mid rows are drawing. There is no easy way to repair app behavior from this state. The
// only rows which still draw correctly during the problem are the top and bottom non-virtualizing rows.
//
// As an alternate repro, you can scroll to near the middle and then resize the bottom of the window, and
// similar virtualization problems can occur. (In our real app, we can be scrolled almost anywhere out of
// the non-virtualizing rows, and make a 1px window resize to break the app. We have a more complex app
// structure, but I'm hoping a fix for this snack will still be applicable to our own symptoms...)
return <NestedFlatLists />;
}
Hopefully I am missing something trivial, as it seems clear React Native is attempting to handle nested FlatLists of the same orientation, and for the most part does great. Until you happen to have enough data items to bring virtualization into play, and even then, only fails for Web. (We've tried upgrading React Native to all the way to 0.67.2 and React Native Web to 0.17.5 - the latest releases - with no luck, and none of the Expo dropdown versions yield correct behavior in the linked Snack either.) What can I change in either sample to have correct virtualization in the nested FlatList?
Short answer is: You can't convince FlatList to virtualize this way correctly. At least currently (0.17), it's broken.
Although I was able to get some FlatList virtualization improvements into React Native Web's 0.18 preview, ultimately the measurement problems are deeper than I could afford to spend more weeks to fully fix. (If someone wants to try picking up from there - I recommend to focus on reconciling RNW's ScrollView versus RN's ScrollView and then digging into the ScrollView's measurements going absolutely haywire in the repro scenario, if replicating RN's evolution of ScrollView to RNW isn't enough.)
It ended up being much faster though to build our own virtualizing list component from scratch. Ours is specialized to our needs ATM so probably won't become open source, but who knows. But if you need to go this route... think about throttling reactions to scroll events and such to ".measure" the container view ref periodically and decide which things you need to render versus just rendering reserved empty space for... etc. There are other approaches but that seems to work.

react-native-qrcode doesn't fit it's element

I am using 'react-native-qrcode' library and trying to create a QR Code, it seems to be working up until the point I want to make it take 100% of it's own container.
I've tried to:
put it in a View, it doesn't work
use flex: 1 on the above mentioned View and on the QR Code
NOTE: I had to change the WebView in the node_modules since now it is a separate library.
import React from 'react';
import QRCode from 'react-native-qrcode';
export default function CardDetails({ navigation }) {
return (
<QRCode
value={"Hello World"}
size={250}
/>
)
}
The problem originates from the QRCode library. This is the code from the library.
If I change the canvas -> context -> size to size * 4 it is will always cover the whole white space and will fit / dynamically change whenever I pass another size.
P.S. still trying to figure it out why x4 is the solution.
return (
<View>
<Canvas
context={{
size: size,
value: this.props.value,
bgColor: this.props.bgColor,
fgColor: this.props.fgColor,
cells: qr(value).modules,
}}
render={renderCanvas}
onLoad={this.props.onLoad}
onLoadEnd={this.props.onLoadEnd}
style={{height: size, width: size}}
/>
</View>
);

Render Three.js Scene in react-360?

I have a BoxGeometry added to a three.js scene. I have also added the scene in ReactInstance. The scene however doesn't seem to be rendered? I have tried this but doesn't work. just wanted to know in what react component the scene would be rendered?
Cube.js:
import {Module} from 'react-360-web';
import * as THREE from 'three';
export default class Cube extends Module {
scene: THREE.scene;
constructor(scene) {
super('Cube123');
this.scene = scene;
}
add() {
const geometry = new THREE.BoxGeometry(100, 100, 100);
const material = new THREE.MeshBasicMaterial({ color: Math.random() * 0xffffff });
const mesh = new THREE.Mesh(geometry, material);
mesh.position.z = -4;
this.scene.add(mesh);
}
}
client.js:
import {ReactInstance, Location, Surface} from 'react-360-web';
import Cube from './Cube';
import * as THREE from 'three';
function init(bundle, parent, options = {}) {
const scene = new THREE.Scene();
const Cube123 = new Cube(scene);
const r360 = new ReactInstance(bundle, parent, {
fullScreen: true,
nativeModules: [ Cube123 ],
scene: scene,
...options,
});
r360.scene = scene;
r360.renderToLocation(
r360.createRoot('CubeModule123'),
new Location([0, -2, -10]),
);
r360.compositor.setBackground('./static_assets/360_world.jpg');
}
window.React360 = {init};
CubeModule.js:
import * as React from 'react';
import {Animated, View, asset, NativeModules} from 'react-360';
import Entity from 'Entity';
import AmbientLight from 'AmbientLight';
import PointLight from 'PointLight';
const Cube123 = NativeModules.Cube123;
export default class CubeModule extends React.Component{
constructor() {
super();
Cube123.add();
}
render() {
return (
<Animated.View
style={{
height: 100,
width: 200,
transform: [{translate: [0, 0, -3]}],
backgroundColor: 'rgba(255, 255, 255, 0.4)',
layoutOrigin: [0.5, 0, 0],
alignItems: 'center',
}}
>
</Animated.View>
);
}
}
I know this doesn't answer the question exactly but take a look at this web page from react 360:
React 360 what is it?
Specifically, take a look at this:
How is React 360 Different from A-Frame?
A-Frame is a framework for building VR worlds using declarative HTML-like components. It has a rich collection of available components from a vibrant community, and is great for creating intricate 3D scenes that can be viewed in VR. We believe that React 360 serves a different use case optimized around applications that rely on user interfaces, or are event-driven in nature. Look through our examples to see the types of things you can easily build with React 360.
Trying to figure out which framework is right for you? Here's a quick test. If your application is driven by user interaction, and has many 2D or 3D UI elements, React 360 will provide the tools you need. If your application consists of many 3D objects, or relies on complex effects like shaders and post-processing, you'll get better support from A-Frame. Either way, you'll be building great immersive experiences that are VR-ready!
How is React 360 Different from Three.js?
Three.js is a library for 3D rendering in the web browser. It's a much lower-level tool than React 360, and requires control of raw 3D meshes and textures. React 360 is designed to hide much of this from you unless it's needed, so that you can focus on the behavior and appearance of your application.
Currently, React 360 relies on Three.js for some of its rendering work. However we are opening up the relevant APIs so that React 360 developers may soon be able to use the 3D rendering library of their choice, including raw WebGL calls.
I know it's probably not the answer you wanted but honestly as someone who has dabbled a lot with aframe and react 360, if you want to use cubes, spherse, shapes, etc. You should go with Aframe. This question has been asked on the github issues on the react360 page and the consensus was the same. Theoretically it is possible, but you'll have to bend over backwards just to make it work.

React Native: How to add two Actions to a button ?

I have a small problem. I want to pass down two Actions to a Button, but I can't seem to figure it out. I am using the react-native-router-flux library. I tried something like this, but It doesn't really work.
If anyone could help that would be awesome. Thanks !
<Button
onPress={Actions.Main1 && Actions.Tab2}
style={{ width: 90, height: 90 }} >
<Text>Show</Text>
</Button>
The onPress prop takes a function, and only a function. There is no syntax for automatically combining two funtions in Javascript. You need to create a new function which executes both actions.
<Button
onPress={(e) => {
Actions.Main1(e);
Actions.Tab2(e);
}}
style={{ width: 90, height: 90 }} >
<Text>Show</Text>
</Button>
Some notes:
I passed the event parameter into both of the actions, since passing just one of the functions (i.e. onPress={Actions.Main1}) itself would pass this parameter as well. This may not be necessary in your case.
The slight issue with this code is that creates a new function every time the render function of this component is called. It's not terrible, but also not ideal. Consider that in the future. I include that optimization in this post because a) we don't see the rest of the implementation of the component, b) I think this question was rudimentary enough for us to just worry about the main concept.

React Native - What is the benefit of using StyleSheet vs a plain object?

What exactly is the benefit of using StyleSheet.create() vs a plain object?
const styles = StyleSheet.create({
container: {
flex: 1
}
}
Vs.
const styles = {
container: {
flex: 1
}
}
There is no benefit. Period.
Myth 1: StyleSheet is more performant
There is absolutely no performance difference between StyleSheet and an object declared outside of render (it would be different if you're creating a new object inside render every time). The performance difference is a myth.
The origin of the myth is likely because React Native team tried to do this, but they weren't successful. Nowhere in the official docs you will find anything about performance: https://facebook.github.io/react-native/docs/stylesheet.html, while source code states "not implemented yet": https://github.com/facebook/react-native/blob/master/Libraries/StyleSheet/StyleSheet.js#L207
Myth 2: StyleSheet validates style object at compile time
This is not true. Plain JavaScript can't validate objects at compile time.
Two things:
It does validate at runtime, but so does when you pass the style object to a component. No difference.
It does validate at compile time if you're using Flow or TypeScript, but so does once you pass the object as a style prop to a component, or if you properly typehint object like below. No difference either.
const containerStyle: ViewStyle = {
...
}
Quoting directly from comment section of StyleSheet.js of React native
Code quality:
By moving styles away from the render function, you're making the code easier to understand.
Naming the styles is a good way to add meaning to the low level components in the render function.
Performance:
Making a stylesheet from a style object makes it possible to refer to it by ID instead of creating a new style object every time.
It also allows to send the style only once through the bridge. All subsequent uses are going to refer an id (not implemented yet).
Also StyleSheet validates your stylesheet content as well. So any error of incorrect style property is shown at time of compiling rather than at runtime when StyleSheet is actually implemented.
The accepted answer is not an answer to the OP question.
The question is not the difference between inline styles and a const outside the class, but why we should use StyleSheet.create instead of a plain object.
After a bit of researching what I found is the following (please update if you have any info).
The advatanges of StyleSheet.create should be the following:
It validates the styles
Better perfomances because it creates a mapping of the styles to an ID, and then it refers inside with this ID, instead of creating every time a new object. So even the process of updating devices is faster because you don't send everytime all the new objects.
It used to be considered that using a StyleSheet was more performant, and was recommended for this reason by the RN team up until version 0.57, but it is now no longer recommended as correctly pointed out in another answer to this question.
The RN documentation now recommends StyleSheet for the following reasons, though I think these reasons would apply equally to plain objects that are created outside of the render function:
By moving styles away from the render function, you're making the
code easier to understand.
Naming the styles is a good way to add meaning to the low level
components in the render function.
So what do I think are the possible benefits of using StyleSheet over plain objects?
1) Despite claims to the contrary my testing on RN v0.59.10 indicates that you do get some validation when calling StyleSheet.create() and typescript (and probably flow) will also report errors at compile time. Even without compile time checking I think it's still beneficial to do run time validation of styles before they are used for rendering, particularly where components that use those styles could be conditionally rendered. This will allow such errors to be picked up without having to test all rendering scenarios.
2) Given that StyleSheet is recommended by the RN team they may still have hopes of using StyleSheet to improve performance in future, and they may have other possible improvements in mind as well, for example:
3) The current StyleSheet.create() run-time validation is useful, but a bit limited. It seems to be restricted to the type checking that you would get with flow or typescript, so will pick up say flex: "1" or borderStyle: "rubbish", but not width: "rubbish" as that could be a percentage string. It's possible that the RN team may improve such validation in future by checking things like percentage strings, or range limits, or you could wrap StyleSheet.create() in your own function to do that more extensive validation.
4) By using StyleSheet you are perhaps making it easier to transition to third party alternatives/extensions like react-native-extended-stylesheet that offer more.
So, today, September of 2021, after reading all the answers and doing some researches, I created a summary about using Stylesheet instead of a plain object.
Based on React Documentation, you should use the stylesheet when the complexity starts to grow.
The style prop can be a plain old JavaScript object. That's what we usually use for example code.
As a component grows in complexity, it is often cleaner to use StyleSheet.create to define several styles in one place.
In the simulator, when using stylesheet will display an ERROR, and when using the plain object will display only a WARNING.
Based on item 2, it looks like it has some validation while compiling. (A lot of people say that’s a myth)
If you need to migrate for a third-party library in the future, for some of them like react-native-extended-stylesheet, if you are using stylesheet, it will be easier.
You have some methods and properties that boost the development. For example, the property StyleSheet.absoluteFill will do position: 'absolute', left: 0, right: 0, top: 0, bottom: 0, or the method compose() will allow you to combine two styles, overriding it.
P.S.: The performance answer looks to be a myth.
My opinion?
Based on item 2 and 5, go to stylesheet instead of plain objects.
I did not find any differences between StyleSheet and plain object, except of typing validation in TypeScript.
For example, this (note the typing differences):
import { View, Text, Image, StyleSheet } from 'react-native';
import logo from './logo.svg';
export default class App extends Component {
render() {
return (
<View style={styles.someViewStyle}>
<Text style={styles.someTextStyle}>Text Here</Text>
<Image style={styles.someImageStyle} source={logo} />
</View>
);
}
}
const styles: StyleSheet.create({
someViewStyle: {
backgroundColor: '#FFF',
padding: 10,
},
someTextStyle: {
fontSize: 24,
fontWeight: '600',
},
someImageStyle: {
height: 50,
width: 100,
},
});
equals to this:
import { View, Text, Image, ViewStyle, TextStyle, ImageStyle } from 'react-native';
import logo from './logo.svg';
export default class App extends Component {
render() {
return (
<View style={styles.someViewStyle}>
<Text style={styles.someTextStyle}>Text Here</Text>
<Image style={styles.someImageStyle} source={logo} />
</View>
);
}
}
const styles: {
someViewStyle: ViewStyle;
someTextStyle: TextStyle;
someImageStyle: ImageStyle;
} = {
someViewStyle: {
backgroundColor: '#FFF',
padding: 10,
},
someTextStyle: {
fontSize: 24,
fontWeight: '600',
},
someImageStyle: {
height: 50,
width: 100,
},
};
Creating your styles via StyleSheet.create will pass though validation only when global variable __DEV__ is set to true (or while running inside Android or IOS emulators see React Native DEV and PROD variables)
The function source code is pretty simple:
create < +S: ____Styles_Internal > (obj: S): $ReadOnly < S > {
// TODO: This should return S as the return type. But first,
// we need to codemod all the callsites that are typing this
// return value as a number (even though it was opaque).
if (__DEV__) {
for (const key in obj) {
StyleSheetValidation.validateStyle(key, obj);
if (obj[key]) {
Object.freeze(obj[key]);
}
}
}
return obj;
}
I would recommend using it because it performs run-time validation during development, also it freezes the object.
i know that this is a really late answer, but I've read that it shows you errors and provides auto completion in editors when you use StyleSheet.