Passing props from one component to other component - reactjs

I am trying to pass value "red" from index.js to box.js yet not working. Basically, I have a component that defines property of box and I want to pass background color "red" from index.js to Box.js component.
// Box.js
import React from "react";
const box = {
// here i would like to get the vlue name assign it to background
background: this.props.name,
width: "250px",
height: "250px"
// more code that defines how the box looks like here
};
export default Box;
/// index.js
import React, { Component } from "react";
import { render } from "react-dom";
import Box from "./Box";
render() {
return (
// when calling Box, I would like to pass the value red to varivable name as shown below
<Box name="red"></Box>
)
}
What am I missing?

You need to create a proper component:
// box.js
import React from "react";
const Box = (props) => {
// here i would like to get the value name assign it to background
const background = props.name;
const width = "250px";
const height = "250px";
// more code that defines how the box looks like here
return (
// jsx code goes here
);
};
export default Box;
in your second snippet, you are not using it properly
// index.js
import React from "react";
import Box from "./box"; // assuming that the file name is box.js and it is in the same folder
const BoxDisplay = (props) => {
return (
<Box name="red"/>
);
};
export default BoxDisplay;
Or if you want an actual Component:
// index.js
import React, {Component} from "react";
import Box from "./box";
export default class BoxDisplay extends Component({
constructor(props) {
super(props)
this.state = { //any initial state you want}
}
render() {
return (<Box name="red"/>)
}
});

There is some confusion in the question, please help us understand your problem in detail.
Your default export name is "card " and you are trying to import
"Box".
what do you mean by main source code?
Your index.js is not having a proper component syntax
please note that you cannot use "this.props" if you are not using a class based component or constructor rather use "props"
try changing the Box component as below:
const Box = (props) => {
return <p style={{background: props.name}}> Content </p>
}

Related

How use Mobx 6 storage with React 17?

I'm completely confused with the rules of mobX - react . Some methods in another project work, but not in this test.
Below is the code of my components from the test application
App.js
import React, { FC } from 'react';
import "./App.css";
import {observer} from 'mobx-react';
import ComponentFirst from './components/ComponentFirst/ComponentFirst';
import ComponentSecond from './components/ComponentSecond/ComponentSecond';
const App: FC = observer(() => {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<ComponentFirst />
<ComponentSecond />
</div>
);
})
export default App;
ComponentFirst
import React, { FC } from 'react';
import {testStoreFirst} from '../../stores/testStoreFirst';
const ComponentFirst : FC = () => {
return (
<div>
<h3>It is First Component</h3>
<p>{testStoreFirst.testText}</p>
<p>{testStoreFirst.textForSecondTestStore}</p>
<button onClick={() => {testStoreFirst.setTestText('New text after click')}}>Click me!!!</button>
</div>
)
}
export default ComponentFirst;
ComponentSecond
import React, { FC } from 'react';
import {testStoreSecond} from '../../stores/testStoreSecond';
import {testStoreFirst} from '../../stores/testStoreFirst';
const ComponentSecond : FC = () => {
return (
<div>
<h3>It is Second Component</h3>
<p>{testStoreSecond.textFromFirstStore}</p>
<button onClick={() =>{testStoreFirst.setTextForSecondTestStore('I can change text from second storage')}}>Click me!!!</button>
</div>
)
}
export default ComponentSecond;
testStoreFirst
import { makeAutoObservable} from "mobx";
class TestStoreFirst {
testText='It is test text from mobX storage';
textForSecondTestStore='this text from First Store!!!';
constructor() {
makeAutoObservable(this);
}
setTextForSecondTestStore = (newText : string) => {
this.textForSecondTestStore = newText;
}
setTestText = (newText: string) => {
this.testText = newText;
console.log('It is not work');
}
}
export const testStoreFirst = new TestStoreFirst()
testStoreSecond
import {makeAutoObservable} from 'mobx'
import {testStoreFirst} from './testStoreFirst'
class TestStoreSecond {
textFromFirstStore = testStoreFirst.textForSecondTestStore
constructor() {
makeAutoObservable(this);
}
}
export const testStoreSecond = new TestStoreSecond();
My question
My App component is subscribed via observe to changes in stores. By clicking on the first button, in 1 component the text in the storage and, accordingly, the text should change, but it does not change. And In the second component, the value for the text field is taken from testStoreSecond. There, the text field is taken from testStoreFirst . When the button is clicked, the method from testStoreFirst is executed which should change the text, but it does not change.
I've read the documentation, but I still don't fully understand how to use the store and achieve "reactivity" and instant change of the component.
You need to wrap every component that uses any observable values with observer decorator, like you did with an App. But in case of App it's actually useless because you are not using observable values there. So just wrap other components and it should work fine.
As for this line textFromFirstStore = testStoreFirst.textForSecondTestStore it won't work like you expected because you just assigned value of testStoreFirst.textForSecondTestStore to textFromFirstStore and that's it.
To make such value reactive you need to use computed value. To make computed you just need to setup a getter function, like that:
class TestStoreSecond {
// ...
get textFromFirstStore() {
return testStoreFirst.textForSecondTestStore
}
// ...
}
// And in React access it just as before (it's a getter, not a function)
<p>{testStoreSecond.textFromFirstStore}</p>

Injecting css to a window.document when using react portal

I'm using react portal to present a printable version of my react view. This is what I do:
import { Component } from "react";
import ReactDOM from "react-dom";
export default class PortalWindow extends Component {
container = document.createElement("div");
externalWindow = null;
componentDidMount() {
this.externalWindow = window.open();
this.externalWindow.document.body.appendChild(this.container);
}
componentWillUnmount() {
this.externalWindow.close();
}
render() {
return ReactDOM.createPortal(this.props.children, this.container);
}
}
import React from 'react';
import './order-print.css';
function OrderPrint(props) {
return (
<div className="order-print">
</div>
);
}
export default OrderPrint;
And there's a component called PurchaseOrder where I do the following:
class PurchaseOrder extends React.Component {
...//omitted for brevity
render(){
{this.state.shouldPrint && (
<PortalWindow>
<OrderPrint order={order} />
</PortalWindow>
)}
}
}
So with a click of a button, I change the shouldPrint state to true and the printable version is displayed in a new window. However, the import './order-print.css'; statement seems to have no effect, so the style is not applied to the div that's in my OrderPrint.jsx file.
Here's the content of the order-print.css file:
.order-print{
border:3 px solid red;
}
So apparently, react does not pass the css to the view that's loaded in a new window. Is there a way to make this possible.
I've actually tried using style instead of className and referencing a const object that has styling information, and in fact, it works. but it's just I prefer using classes to inline styling.

Simple passing of Value from one Component to another through context

I'm new to react native and would like to use Context to keep a socket connection alive between screens in the future. For now, I tried to learn the concept of context just to pass simple values around but the value doesn't get sent.
Tried to follow the tutorial here, but by sending simple values instead.
I create my ValueContext in ValueContext.js here.
import React from 'react';
const ValueContext = React.createContext();
export default ValueContext;
Here's my LoginScreen.js where I set context provider.
import React, { Component } from 'react';
import ConnectionScreen from './ConnectionScreen';
import ValueContext from './ValueContext';
const testValue = 5;
export const sendValue = props => (
<ValueContext.Provider value={testValue}>
<ConnectionScreen />
</ValueContext.Provider>
)
class LoginScreen extends Component {
render() {
return()
}
}
Then in my ConnectionScreen.js
import React, { Component } from 'react';
import { View, Alert } from 'react-native';
import LoginScreen from './LoginScreen';
import ValueContext from './ValueContext';
export const receiveValue = props => (
<ValueContext.Consumer>
{testValue => <ConnectionScreen {...props} testValue={testValue} />}
</ValueContext.Consumer>
)
class ConnectionScreen extends Component {
showAlertValue = () => {
Alert.alert(this.props.testValue);
}
render() {
return(
<View>
{this.showAlertValue()}
</View>
)
}
}
So after setting the value in LoginScreen, I would like to access it in ConnectionScreen. All I get in my alert box is an empty box with no values. Am I doing something wrong here?

Component is declared but never used

I keep getting this weird message and React isnĀ“t rendering my component. I am pretty sure I am rendering and importing it correctly:
Container:
import searchBar from "./searchBar";
class ItemList extends Component {
render() {
return (
<searchBar/>
);
}
}
searchBar
import React, { Component } from 'react';
const searchBar = () => {
return <div>ssuhsuhuhsususu</div>;
}
export default searchBar
Change to
const SearchBar = () => {
return <div>ssuhsuhuhsususu</div>;
}
export default SearchBar;
I you give name in small caps it will be considered as HTML tag such as
<p>, <div>
So your component should always be starting with CAPS.
If you want to use component which name start with lowercase then use can use following tips:
Just assign it to capitalised variable before using it.
import searchBar from "./searchBar";
const Foo = searchBar;
<Foo/>
Full Code:
import searchBar from "./searchBar";
const Foo = searchBar;
class ItemList extends Component {
render() {
return (
<Foo/>
);
}
}

Passing Props between components

I am creating a bit of a playground to learn react and I've hit a road block with passing props between components. I essentially have two components, 1 that is the base component and then another that renders it out on the page with some extras (which i've removed for simplicity sake). I essentially want to be able to reuse the items in other places.
I'd like to be able to, when rendering the component in the example specify if it is type=submit if nothing specified default to type=button.
I'm clearly missing the point here because I get the error Cannot read property 'props' of undefined with the below code. Any help would be appreciated
Button Component
import React, {PropTypes} from 'react';
import './button_component.scss';
const propTypes = {
type: PropTypes.string
}
const ButtonComponent = () => {
return <button type={this.props.type}>button</button>
}
ButtonComponent.propTypes = propTypes;
export default ButtonComponent;
Then I have a component that outputs my item
import React from 'react';
import ButtonComponent from './button_component';
import Example from './example'
export default () =>
<Example>
<ButtonComponent type='button' />
</Example>;
ButtonComponent is a functional component. Hence, you can not use this.props in its code.
You should introduce props argument
const ButtonComponent = (props) => {
return <button type={props.type}>button</button>
}
Object destructuring and defaultProps can help you make your code simpler
const ButtonComponent = ({ type }) => {
return <button type={type}>button</button>
}
ButtonComponent.defaultProps = {
type: 'button'
}
then you can simply put <ButtonComponent /> to render a button.

Resources