Unable to pass props between classes using React - javascript

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/0.14.3/react-dom.min.js"></script>
class carSelection extends React.Component {
render(){
return(
<Button> {this.props.name} </Button>
);
}
}
class App extends Component {
constructor(props) {
super(props);
this.state = {
currentPage: 'Your Car',
carSelected: null
};
}
renderCarsList() {
//const carNames = ['porsche', 'Ford', 'Subaru'];
const carName = "Porsche";
return (
//{carNames.map((carName) => <carSelection name = {carName} />)} was inside div
<div>
<carSelection name = {carName} />
</div>
);
}
render() {
const menuItems = [
"Your Car"
];
return (
<Grid centered celled padded>
<Grid.Row>
<Grid.Column width={2}>
{menuItems.map(item => (<Button fluid>{item} </Button>))}
</Grid.Column>
<Grid.Column width={10}>
{this.renderCarsList()}
</Grid.Column>
</Grid.Row>
</Grid>
);
}
}
export default App;
I am trying to pass a prop from renderCarsList() to carSelection. Like this it builds but does not display any buttons. I have been trying to do it the same way as the react tic tac toe tutorial. I also tried with carSelection as a function but no luck.
I have not been able to do anything with this form:<carSelection name = {carName} />. When it was a function it worked using carSlection() but I cannot pass props like that.

Write CarSelection with capital C. Lower-case names are considered to be HTML tags.

You shouldn't use camel-case naming in your class name. Try to use pascal naming instead.
eg: CarSelection

Your carSelection component should capitalize the first letter。React will recognize the component with Capital lowercase to be native html element.

Related

How to Put Drawer below the Header React-JS

I'm new in react and I have useStyles in my code for changing the style of the drawer
const useStyles = makeStyles((theme) => ({
drawer: {
marginTop: 56,
}
}));
class PageMenu extends React.Component {
GetMenuItems() {
var classes = useStyle();
<div>
<Drawer
open={this.props.DrawerOpen}
anchor="right"
variant="persistent"
onClose={this.fixthew}
classes = {classes.drawer}
>
---some element------
</Drawer>
<\div>
}
}
render() {
return(
<div>
{GetMenuItems}
</div>
)
}
the problem is ReferenceError: useStyle is not defined and GetMenuItems should be before the render
Use withStyles instead of makeStyles for Class Components.
many mistakes:
You are using the useStyles hook in a class component (hooks are only for functional components)..
You defining the component as one of class methud... u shouldn't do so..
You pass the class in the classes prop instead of in className prop
instead use a functional component like so:
function MenuItems(){
var classes = useStyle();
return <div>
<Drawer
open={this.props.DrawerOpen}
anchor="right"
variant="persistent"
onClose={this.fixthew}
className = {classes.drawer}
>
---some element------
</Drawer>
<\div>
}
function PageMenu(){
return(
<div>
<MenuItems/>
</div>
)
}
if you are a beginner i can advice you to use functional component with hooks and learn the diffrences...
also, Matirial-Ui is a tough Library u better learn the customizations in this library and the ways they offer to style components... (there is many though..)

How to write a wrapper around a material UI component using React JS?

I am using Material UI next library and currently I am using List component. Since the library is in beta, lot of its parameter names get changed. To solve this I am planning to write a wrapper around the required components so that things wont break. My list component :
<List dense>
<List className={classes.myListStyles}>
<ListItem disableGutters/>
</List>
</List>
How should I write the wrapper for the List(say myListWrapper) and ListItem so that the wrapper component can handle props and pass them to the actual MUI list component inside?
I had worked on MUI wrappers, writing my own library for a project. The implementation we are focusing, is to pass the props to inner/actual-MUI component from the our wrapper component. with manipulation. In case of wrapping props for abstraction.
Following is my approach to the solution:
import { List as MaterialList } from 'material-ui/List';
import { React } from 'react';
import { ListItem as MaterialListI } from 'material-ui/ListItem';
class List extends MaterialList {
constructor(props){
const propsToPass = {
prop1 : change(props.prop1),
...props
}
super(propsToPass);
}
};
class ListItem extends MaterialListItem {
const propsToPass = {
prop1 : change(props.prop1),
prop2 : change(props.prop2),
...props
}
super(propsToPass);
}
};
class App extends React.Component {
render () {
return (
<List prop='value' >
<ListItem prop1={somevalue1} prop2={somevalue2} />
<ListItem prop1={somevalue1} prop2={somevalue2} />
<ListItem prop1={somevalue1} prop2={somevalue2} />
</List>
)
}
};
Above code will allow following things to do with your component:
You can use the props with exact names, as used in Material UI.
You can manipulate/change/transform/reshape you props passed from outside.
If props to you wrapper components are passed with exactly same names as MUI is using, they will directly be sent to the inner component. (... operator.)
You can use Component with exact same name as material is using to avoid confusion.
Code is written according to advance JSX and JavaScript ES6 standards.
You have a space to manipulate your props to pass into the MUI Components.
You can also implement type checking using proptypes.
You can ask for any confusion/query.
You can write it like this:
const MyList = props => (
<List
{/*mention props values here*/}
propA={props.A}
propB={props.B}
>
{props.children}
</List>
)
const MyListItem = props => (
<ListItem
{/*mention props values here*/}
propA={props.A}
propB={props.B}
>
{props.children}
</ListItem>
)
Now you need to use MyList and MyListItem, decide the prop names for these component (as per your convenient), and inside these component map those values to actual Material-UI component properties.
Note:
If you are using the same prop names (same name as material-ui component expect) for your component then you can write like this also:
const MyList = ({children, ...rest}) => <div {...rest}>{children}</div>
const MyListItem = ({children, ...rest}) => <p {...rest}>{children}</p>
Check this example:
const A = props => <div>{props.children}</div>
const B = props => <p>{props.children}</p>
ReactDOM.render(
<A>
<A>
<B>Hello</B>
</A>
</A>,
document.getElementById('app')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app' />

React - prop is undefined when loading the same component

I am facing an issue with a React component which I want to use a certain prop in one case and another prop in a different case. Let me show you what I mean.
class GizmoComponent extends React.Component {
render() {
return (
{
this.props.SomeBoolean
?
<WidgetColumn {...this.props} field1={this.props.field2}/>
:
<WidgetColumn {...this.props} field1={this.props.field1}/> {/* field1 is already in the props but I'm being explicit */}
}
);
}
}
class WidgetColumn extends React.Component {
render() {
return (
{
this.props.field1.subfield
?
<div>{/* Extensive use of this.props.field1 throughout this component*/}</div>
:
<div></div>
}
);
}
}
Basically, what I am trying to do is that because WidgetColumn makes extensive use of the this.props.field1, I want to replace the getting of that data with a field2. Everything else remains the same. Just get the data from a different item in a certain case: SomeBoolean.
However, I am getting an error on the this.props.field1.subfield saying that this.props.field1 is undefined so I can't get the subfield of something that's undefined. This only occurs when I add the <WidgetColumn {...this.props} field1={this.props.field2}/> line to the code.
Why is it undefined since I am defining what it is in the prop?
At first, make sure that SomeBoolean and field1.subfield/field2.subfield properties are passing properly.
My recomendation is: try not to spread props object {...this.props} when passing parameters to the WidgetColumn.
As I understood GizmoComponent has field1 and field2 props:
GizmoComponent.propTypes = {
field1: PropTypes.object
field2: PropTypes.object
}
So when you will spread GizmoComponent props into another component like:
// NOTE: there are this.props.field1 and this.props.field2 are available
<WidgetColumn {...this.props} />
The result will be the same as you will write:
<WidgetColumn field1={this.props.field1} field2={this.props.field2} />
It's possible that you have conflict and spread object rewrites the value of the props that you defined manually.
Try to pass field property on next way:
class WidgetColumn extends React.Component {
render() {
return this.props.field.subfield
? <div>The field is subfield</div>
: <div>The field is NOT subfield</div>
}
}
class GizmoComponent extends React.Component {
render() {
return this.props.SomeBoolean
? <WidgetColumn field={this.props.field2} />
: <WidgetColumn field={this.props.field1} />
}
}
class Example extends React.Component {
render() {
return (
<p>
<GizmoComponent field1={{ subfield: true }} field2={{ subfield: false }} SomeBoolean={true} />
<GizmoComponent field1={{ subfield: true }} field2={{ subfield: false }} SomeBoolean={false} />
</p>
);
}
}
ReactDOM.render(
<Example />,
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
You have to declare property while Rendering Component.
Like
<WidgetColumn props={this.props} field1={this.props.field2}/>
If you use this then you can access all props of parent component in child component.
That's it.

Set Heading Level With Props React

Just wondering if there is anyway to set heading levels by passing props down to the base component.
Example:
Base Component
class Heading extends Component {
render() {
return (
<h{this.props.headinglevel} className={this.props.titleStyle}>
{this.props.title}
</h{this.props.headinglevel}>
);
}
}
export default Heading;
Parent Component (Passing Props)
class HomeHeader extends Component {
render() {
return (
<Heading headinglevel="1" titleStyle="big-header" title="Hello World" />
)
}
}
export default HomeHeader;
When I try this I get a syntax error.
Yup! The way to make your tag a variable is as such:
render() {
const Tag = 'h1';
return <Tag>{/* some code here */}</Tag>;
}
Notice that Tag is capitalized. It is required you capitalize a tag variable so React understands it's not just a normal HTML element.
So in your case, you could do something like:
render() {
const Tag = 'h' + this.props.headinglevel; // make sure this has a default value of "1" or w/e
return (
<Tag className={this.props.titleStyle}>
{this.props.title}
<Tag>
);
}
(If you're being safe, you may want to add some check so this.props.headinglevel can only be 1-6.)

switch components in react js

I'm doing a singlepage application and would like to switch a component.
Here is an image how it looks like:
If I click on the button in component 3, I will switch the component 3 with 5.
So maybe like component 3 is a view of all projects and if I click on one project, I will see a detail view of the project with some information.
I created two different components for this.
All other components should stay at the same place.
Here is my code how I switch the components:
this.state.detailVisible
? <ProjectDetailView/>
: null
I'm not sure if is the correct react way to do it. Also I have two different css files for component 3 and 5. If I'm switching the two component, I have some class name irritations with my css.
If it's a better way to do it with routers?
How is the react way to do it?
thanks for your help :)
It all depends on your needs, if you need to render both component3 and component5 then a route won't be much of a help.
If you need to render only one of them then a route can be handy.
as for the syntax i prefer this:
this.state.detailVisible && <ProjectDetailView/>
here is a simple example:
const components = ["Component1", "Component2", "Component3"];
class Component extends React.Component {
constructor(props) {
super(props);
this.state = {
showDetails: false
};
this.onComponentClicked = this.onComponentClicked.bind(this);
}
onComponentClicked(e) {
this.setState({
showDetails: !this.state.showDetails
});
}
render() {
const { name } = this.props;
const { showDetails } = this.state;
return (
<div>
<div>Component{name}</div>
<button onClick={this.onComponentClicked}>Toggle Details</button>
{showDetails && <ComponentDetails name={name} />}
</div>
);
}
}
const ComponentDetails = ({ name }) => (
<div>
<div>Details of component{name}</div>
</div>
);
class App extends React.Component {
render() {
return (
<div>
<h2>Parent</h2>
{components.map(c => {
return (
<div>
<Component name={c} />
<hr />
</div>
);
})}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Categories

Resources