I am trying to pass a state as props to another component. The child component (a button on the page) isn't receiving any props. I did a console.log to print the props received from the parent but I get an empty object {}. What am I doing wrong here?
Here is an excerpt from my code:
loan.js (Parent)
<ForecloseBtn id={this.state.lead_id} foreclose={this.state.isForeclosed } test="xyz"/>
ForecloseBtn.js (Child)
import React from 'react';
import { render } from 'react-dom';
class ForecloseBtn extends React.Component {
constructor(props) {
super(props);
console.log(this.props);
this.state = {
lead_id: this.props.id,
isForeclosed: this.props.foreclose,
sample: this.props.test
};
}
render() {
return (
......
)
}
};
const App = () => (
<ForecloseBtn />
);
export default App;
You have to add a propTypes like this
static propTypes = {
id: object.isRequired,
foreclose: func.isRequired,
}
and for sure
import {
func,
object,
} from 'prop-types'
You can check my fiddle
Pass props to child
Hope this helps.
Related
I am trying to get adaptValue from Component1 and use it in Component2. For some reason this does not work since my adaptValue is always null/undefined. Is it because Parent is a functional component?
const Parent = (props) => {
const [adaptValue, setAdapt] = useState(null);
return (
<div>
<Component1 setAdapt={setAdapt}/>
<Component2 adaptValue={adaptValue}/>
</div>
)
}
export default class Component1 extends Component {
constructor(props) {
super(props);
}
adaptValue = (value) =>{
DO_SOMETHING_WITH_VALUE
}
componentDidMount() {
this.props.setAdapt(this.adaptValue);
}
render() {
return something;
}
}
export default class Component2 extends Component {
constructor(props) {
super(props);
}
someFunction = (value) =>{
...
//adaptValue is always undefined
this.props.adaptValue(value)
...
}
render() {
return something;
}
}
UPDATE Made the parent a class component in the end and all works. Wondering whether this is a compatibility issue between functional or class-based components.
When passing setAdapt to Component1 ... setAdapt is already a function. There is no need to wrap it in another one. Component1 will modify the value, and Component2 will display it. Function Components have nothing to do with the behavior.
Try ...
App.js
import React, { useState } from "react";
import "./styles.css";
import Component1 from "./Component1";
import Component2 from "./Component2";
export default function App() {
const [adaptValue, setAdapt] = useState(null);
return (
<div>
<Component1 setAdapt={setAdapt} />
<Component2 adaptValue={adaptValue} />
</div>
);
}
Component1.js
import React, { Component } from "react";
export default class Component1 extends Component {
handleClick = () => {
this.props.setAdapt("New Value");
};
render() {
return <button onClick={() => this.handleClick()}>Set Value</button>;
}
}
Component2.js
import React, { Component } from "react";
export default class Component2 extends Component {
render() {
return !!this.props.adaptValue ? (
<h1>{`"${this.props.adaptValue}" <- Value of adaptValue`}</h1>
) : (
<h1>adaptValue Not Assigned</h1>
);
}
}
Sandbox Example ...
I want to get props from Redux in the child component. But {this.props} is empty object. I am using react-redux connect to get the props. It is working in parent component and we can pass to child component to get the props but I need to get from child component
Login
```import React, { Component } from 'react'
import { Test } from './Test'
export default class Login extends Component {
render() {
return (
<div>
<Test hi=""/>
</div>
)
}
}```
Test
import React, { Component } from 'react'
import { connect } from 'react-redux'
export class Test extends Component {
render() {
console.log(this.props)
return (
<div>
vddfff
</div>
)
}
}
const mapStateToProps = (state) => ({
})
const mapDispatchToProps = (dispatch) => {
return {
selectedData: (val) => {
console.log("object")
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Test)
The problem here is that you are trying to use the Test component you wrote instead of the Higher order component which is being returned by the connect() from react-redux
You don't need to export the Test class.
In login.js file, use
import Test from './Test'
instead of
import {Test} from './Test'
See it in action here.
https://codesandbox.io/s/sample-test-app-q5srf
You used the wrong component. In login you need to import:
import Test from './Test'
You imported Test wich is not connected to redux (that pushes the redux props).
Parent Component
import React, {Component} from 'react';
import NameContainer from '../nameContainer/index'
export default class Vishal extends Component {
constructor(props) {
super(props);
this.state = {
data: "This is the data"
}
}
render() {
return(
<div>
<p>My name is Vishal</p>
</div>
)
}
}
Child Component
import React, {Component} from 'react';
export default class NameContainer extends Component {
}
How can I use a callback function and import from the child component? Any help will be highly appreciated
This violates the top-down philosophy of react and any sort of way to hijack that is probably not the direction you want to go.
What I think you mean to do is have state in the parent container, and allow the child to display and update that state.
i.e Parent.JS
import React, {Component} from 'react';
export default class NameContainer extends Component {
this.state = { name: 'Vishal' }
handleChange = this.setState({name: event.target.value})
render() {
return (
<Vishal name={this.state.name} handleChange={this.handleChange} /> )}
then in child js // Vishal.js
{ ...boilerplate }
handleChange = this.props.handleChange; // and e.g a button or textfield to allow the user to update the name.
render() {
return ( {this.props.name}) }}
this will display the stateful data of name (initalized as 'Vishal') from Parent.js in the child component, Vishal.js
I have a code like this in my React application:
import React from 'react';
import ReactDOM from 'react-dom';
import ComponentB from './ComponentB';
class ComponentA extends React.Component {
constructor(props) {
super(props);
this.condition = this.props.condition;
}
render() {
return ReactDOM.createPortal(
<div id="abc"></div>,
document.getElementById('xyz'))
}
componentDidMount() {
ReactDOM.createPortal(
<div>
{
this.condition &&
<ComponentB />
}
</div>,
document.body)
}
}
Basically, I want to render ComponentB only after ComponentA has been mounted to DOM. Hence I have put the code for ComponentA inside componentDidMount of ComponentB. But still ComponentB is rendering before ComponentA has finished mounting to DOM.
Why is this happening and what's the solution to this problem?
I am not sure why you are using createPortal. But if you just want to achieve your goal, you just need to set your state condition in componentDidMount of first component telling to start rendering of your second component.
See if this helps.
const ComponentB = () => {
return (
<div>Hi is is componentB</div>
);
}
class ComponentA extends React.Component {
constructor(props) {
super (props);
this.state = {
renderB: false
};
}
componentDidMount() {
this.setState({
renderB: true
});
}
render () {
let {renderB} = this.state;
return (
<div>
<h3>Hey i am component A</h3>
{
renderB? <ComponentB /> : null
}
</div>
);
}
}
I have a React component that I am trying to test using Enzyme/Jest. I am trying to figure out what the most appropriate test would be to ensure the component has rendered.
My component has a prop shouldRender that, if false, will cause the component to not render. My component looks like this:
import React from 'react';
const propTypes = {
shouldRender: React.PropTypes.bool,
};
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
foo: 'bar',
};
}
render() {
if (!this.props.shouldRender) {
return null;
}
return (
<div>
<span>My component</span>
</div>
);
}
}
MyComponent.propTypes = propTypes;
export default MyComponent;
I have a test that looks like this:
import React from 'react';
import { shallow } from 'enzyme';
import MyComponent from '../MyComponent';
describe('MyComponent', () => {
it('Should render if we want it to', () => {
const component = shallow(<MyComponent shouldRender />);
expect(component).toBeDefined(); // Passes
});
it('Should not render if we do not want it to', () => {
const component = shallow(<MyComponent />);
expect(component).not.toBeDefined(); // Does not pass, as component isn't undefined.
});
});
I'd like the second test to fail, as the component isn't rendering. Is there a better way to go about testing whether or not a component has rendered?
Happy to provide any more information if it is needed.
Thanks!
So I've had a chat to some people and decided that maybe I am going about this the wrong way.
It's probably a better idea to determine whether or not this gets rendered by the parent component, otherwise any time I want to use MyComponent, I am going to have to pass this shouldRender prop into it.
MyComponent now looks like this:
import React from 'react';
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
foo: 'bar',
};
}
render() {
return (
<div>
<span>My component</span>
</div>
);
}
}
MyComponent.propTypes = propTypes;
export default MyComponent;
and MyParentComponent that uses MyComponent looks like this:
import React from 'react';
const propTypes = {
myComponent: React.PropTypes.bool,
};
class MyParentComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
boz: 'baz',
};
}
render() {
return (
<div>
{ this.props.myComponent &&
<MyComponent />
}
</div>
);
}
}
export default MyComponent;
Not only does allow MyComponent to be more reusable, it removes the need for the test I wanted to write altogether. Thank you to everyone that looked at this.
I think Jest's snapshot testing is what you need. With snapshot testing when a test fails you can check to see if it's intended or unintended change. Check out their example here