What is the better way to structure components' props? - javascript

I'm now testing some Material-UI components and can't understand 1 moment. For example, in List component. Why do they use syntax like this?
<List component="nav">
<ListItem
button
selected={selectedIndex === 0}
onClick={(event) => handleListItemClick(event, 0)}
>
<ListItemIcon>
<InboxIcon />
</ListItemIcon>
<ListItemText primary="Inbox" />
</ListItem>
</List>
it seems to me that you can just use this approach:
<List component="nav"
items=[
{
icon: 'inbox',
text: 'Inbox',
onClick: () => handleListItemClick()
}
]
/>
Оr you can also use render props.
What makes their approach more convenient? after all, they clearly chose it for some reason

Although I'm not familiar with their style, the example seems simple to follow maybe for presentation purposes. For real use application usage you may want to do your array style example.

Related

material-ui and navigation button with component

Following the example at https://material-ui.com/guides/composition/#button, i define in my main page a button:
<BrowserRouter>
<Box m={2}>
<Button
size="large" variant="contained"
color="primary" endIcon={<TimerIcon />}
fullWidth={true}
component={SubmitTime}>
Enter hours
</Button>
</Box>
</BrowserRouter>
Documentation states:
Routing libraries
The integration with third-party routing libraries is achieved with the component prop. The behavior is identical to the description of the prop above. Here are a few demos with react-router-dom. It covers the Button, Link, and List components, you should be able to apply the same strategy with all the components.
Now, based on the above, my understanding would be that the above would render a button that, when clicked, would get me to the SubmitTime component. Instead, I get the component itself rendered:
Being new to React and react-router-dom, i think i am doing something wrong, but can't understand what?? Any clue appreciated.
I tried adding 'to' to the component, like so, with same results:
<Button
size="large" variant="contained"
color="primary" endIcon={<TimerIcon />}
fullWidth={true}
component={SubmitTime} to="/timesheet">
Enter hours
</Button>
component is supposed to be the style of the button. Here you can see an example of using the button as a link: https://material-ui.com/components/buttons/#cursor-not-allowed. Also try reading the api: https://material-ui.com/api/button/#props
If you want your button to function as a link, add the href="/timesheet" attribute to it. Else push the route to the history:
const history = useHistory();
...
<Button
size="large" variant="contained"
color="primary" endIcon={<TimerIcon />}
fullWidth={true}
onClick={() => history.push("/timesheet")}
>
Enter hours
</Button>

React - Having trouble onClick (React)

((New to React))
I am trying to get the different jobs (salary.job.id listed above) to pass through on click. The jobs are already being obtained through an axios call.
Is there an easier way to accomplish this? Also, is it correct to call the this.makesalary twice (once in componentDidMount and another through the click?
This is what i am trying to pass through
makesalary(slug = "charlotte") {
axios.get(`https://api.teleport.org/api/urban_areas/slug:${slug}/salaries/`)
.then(results => {
console.log(results)
const filteredata = results.data.salaries.filter(salary=>{
if(salary.job.id === "UX-DESIGNER"){
return true
}
if (salary.job.id === "WEB-DEVELOPER"){
return true
}
if(salary.job.id === "MOBILE-DEVELOPER"){
return true
}
return false
})
this.setState({salaries:
filteredata
})
}
)
}
Can this be called twice? and is the placement correct?
componentDidMount (){
this.makesalary(this.props.slug)
}
_onclick(salary){
this.makesalary(salary.job.id)
}
Here is the render
<div>
<h2>What Tech Job are you in currently?</h2>
<CardGroup>
<Card>
<Card.Img variant="top" src= {Mobileicon} />
<Card.Body>
<Card.Title>Mobile Developer</Card.Title>
<Card.Text>
Mobile Developer specialise in mobile technology such as building apps for Google's Android, Apple's iOS and Microsoft's Windows Phone platforms.
</Card.Text>
</Card.Body>
<Card.Footer>
<Button variant="danger" onClick={this._onclick}>Pick this Job!</Button>{' '}
</Card.Footer>
</Card>
<Card>
<Card.Img variant="top" src= {UXicon} />
<Card.Body>
<Card.Title>UX Designer</Card.Title>
<Card.Text>
In a nutshell, the UX designer is responsible for how a product or website feels.
The UX designer's job is to zero in on users' underlying emotional and functional needs.
</Card.Text>
</Card.Body>
<Card.Footer>
<Button variant="danger" >Pick this Job!</Button>{' '}
</Card.Footer>
</Card>
<Card>
<Card.Img variant="top" src={Webdevelop} />
<Card.Body>
<Card.Title>Web Developer</Card.Title>
<Card.Text>
A Web Developer is responsible for the coding, design and layout of a website according to a company's specifications.
As the role takes into consideration user experience and function, a certain level of both graphic design and computer programming is necessary.
</Card.Text>
</Card.Body>
<Card.Footer>
<Button variant="danger" >
Pick this Job!</Button>{' '}
</Card.Footer>
</Card>
</CardGroup>
</div>
)
}
I'd like to help out so I'm going to point out a few things and also suggest a bit. Before starting, I have to apologize if something I say is incorrect and would appreciate it if someone would correct me on such.
I'm also going to assume that your makesalary function is defined above (where the Axios call is shown).
In your componentdidmount method, you call makesalary with the parameter you have obtained from props. If your props are valid, this is absolutely fine.
You also happen to call makesalary in the _onclick method. I'd suggest you rename it to something such as handleClick or onClickHandler to make it more clear, and remove the _ in front as it's unnecessary (unless it's a convention you are using). The method itself looks fine.
When you are calling _onclick with the button, keep in mind that it's going to pass an event into the method. You should handle this by either passing a function such as () => _onclick(salary) to onClick at the button (since you don't intend to use the event for anything). Aside from handling the event correctly, this also helps you to pass in the correct parameter for _onclick. In the code snippet you have provided, it seems that onClick is not passing any parameters to the _onclick function.
I'd recommend you to read up on the official React documentation regarding this:
https://reactjs.org/docs/handling-events.html.
Hope I've helped!
EDIT: In case you're wondering, it's absolutely okay to call the same method twice!

Making a react component clickable

I have a functional REACT component, code is as follows
const MobileListing = (props) => {
function handleClick() {
console.log('in cardClick');
}
return (
<div>
<Row>
<Card onClick={() => handleClick()} style={{cursor : 'pointer'}} >
<Card.Img variant="top" src="holder.js/100px180" />
<Card.Body>
<Card.Title>Card Title</Card.Title>
<Card.Text>
Some quick example text to build on the card title and make up the bulk of
the card's content.
</Card.Text>
<Button variant="primary">Go somewhere</Button>
</Card.Body>
</Card>
</Row>
</div>
);
}
export default MobileListing;
I want to make the entire card clickable. I read through a post on stack overflow Making whole card clickable in Reactstrap which talks about using an anchor tag, but that doesn't work for me.
Can someone help me understand what I am doing wrong?
A card looks like this on my site and I want to make the whole card clickable.
You can use the onClick either on the top-level div element for this, or, in case there would be more cards inside the Row you can wrap each with a div and give it the onClick, property.
such like:
<div>
<Row>
<div onClick={handleClick}>
<Card style={{ width: '18rem', cursor : 'pointer' }} >
<Card.Img variant="top" src="holder.js/100px180" />
<Card.Body>
<Card.Title>Card Title</Card.Title>
<Card.Text>
Some quick example text to build on the card title and make up the bulk of
the card's content.
</Card.Text>
<Button variant="primary">Go somewhere</Button>
</Card.Body>
</Card>
</div>
</Row>
</div>
It is better to wrap it around with an anchor tag because clickable things should be links if they go to places, and should be buttons if they do things.
Using click handlers with other things just make things inaccessible.

How to change background colour transparent in React-Native checkBox?

In my scenario, I am trying to implement react native check box for android and iOS using Reactnative Elements. Here, I need to change checkbox with label background colour. It is showing full white but how to change it is transparent?
https://react-native-elements.github.io/react-native-elements/docs/checkbox.html
<CheckBox
checkedIcon={<Image source={require('../checked.png')} />}
uncheckedIcon={<Image source={require('../unchecked.png')} />}
checked={this.state.checked}
onPress={() => this.setState({checked: !this.state.checked})}
/>
Just use the containerStyle prop (https://react-native-elements.github.io/react-native-elements/docs/checkbox.html#containerstyle)
The easiest (but also ugliest) way would be to say
<CheckBox
containerStyle ={{backgroundColor: 'transparent'}}
checkedIcon={<Image source={require('../checked.png')} />}
uncheckedIcon={<Image source={require('../unchecked.png')} />}
checked={this.state.checked}
onPress={() => this.setState({checked: !this.state.checked})}
/>

Unable to align ListItem text

I have this material-ui list:
<List dense>
{this.state.issues.map((item, i) => {
return <Link target="_blank" to={item.issue_url} key={i}>
<ListItem button>
<ListItemText primary={item.issue_state}/>
<ListItemSecondaryAction>
<IconButton>
<ArrowForward/>
</IconButton>
</ListItemSecondaryAction>
</ListItem>
</Link>
})
}
</List>
issue_state is obtained from MongoDB. Can I add another column to my list showing another field from the database? I tried:
<ListItemText primary={item.issue_state}/>
<ListItemText primary={item.issue_title}/>
This displays what I want but the issue_title test is centered. I'd like it left aligned. Can this be done?
ListItemText component renders with the following CSS style that allows it to be flexible to grow and shrink according as the width and height of its content.
flex: 1 1 auto;
Its ancestor ListItem component renders as an inline-flex.
AFAICT, the results you're looking to achieve can't be done without overriding these styles. Not to worry, there are other ways to go that uses available APIs exposed in the component.
Never mind that the name for the component seems to be misleading that its usage is specific for rendering text in the list item.
A closer look in the ListItemText component API documentation shows that the primary property is of the node type.
That implies that the ListItemText can be used to render string, function, and React.Element in a manner similar to the snippet below.
<ListItemText primary={<div>Foo<br/>Bar<br/>Baz</div>} />
There is also the secondary property that renders the elements with textual emphasis.
<ListItemText primary="Foo" secondary={<div>Bar<br/>Baz</div>} />
If you need more control over the children of the ListItemText, the API allows for the flexibility to write it this way
<ListItemText>
<Typography variant="subheading">Foo</Typography>
<Typography variant="body1" color="textSecondary">Bar</Typography>
<Typography variant="body1" color="textSecondary">Baz</Typography>
</ListItemText>

Categories

Resources