React/Redux Form ReRender Method - reactjs

I would like to insert advertisement block (such as Google Adsense) inside of items list. I am using the react-redux & react-connect. Even if I need to refresh the feed and rerender, I would like to run the render of ad-block div only one time. Is there any way we can do this?
render(){
const { feed } = this.props;
return(
<div>
<div class="ad-block"><!-- Need To Render one time --></div>
<div class="items">
{_.map(feed.data, item => {
return <div class="item">.......</div>
})}
</div>
<div class="ad-block"><!-- Need To Render one time --></div>
);
}

How about to split it in 3 components?
export const Something = () => (
<>
<AdBlock>
<Feed>
<AdBLock>
<>
);
And connect Feed separately through Redux.

Related

Create a custom Hook for splitting strings (React JS)

I'm working with React JS (hooks) for recently. For a project, I need to split many strings in different divs. So, I created a function to this, that saves me some time! My actual question is : Should I create a custom Hook instead of my function ?
Of course, the actual code works, but as a beginner, I don't know if my way is clean. I need feedbacks cause my main goal to write the best and clear code as possible.
// Splitting Texts
const splitText = str => {
return (
<div>
{str.split(' ').map((item, index) => {
return (
<div key={index}>
{item}
</div>
);
})}
</div>
);
};
// Main App
export default function App() {
const name = splitText('Lucie Bachman');
const description = splitText('Hey, this is my first post on StackOverflow!');
return (
<div className="App">
<h1>{name}</h1>
<h2>{description}</h2>
</div>
);
}
Expected results :
<h1>
<div>
<div>Lucie</div>
<div>Bachman</div>
</div>
</h1>
I'm super excited to have joined the community!
Thanks to you, and take care.
Lucie Bachman
A custom hook is something that uses out of the box react hooks to actually provide a logic and return data.
If the function returns JSX, its actually just a function or can be used as a functional component
Since you only want to split string once you can convert it into a component and use React.memo to optimize rendering
// Splitting Texts
const SplitText = React.memo(({str}) => {
return (
<div>
{str.split(' ').map((item, index) => {
return (
<div key={index}>
{item}
</div>
);
})}
</div>
);
});
// Main App
export default function App() {
return (
<div className="App">
<h1><SplitText str={'Lucie Bachman'} /></h1>
<h2><SplitText str={'Hey, this is my first post on StackOverflow!''} /></h2>
</div>
);
}

Jest: functional component array list not mapping after adding element

I am trying to list person by clicking onClick function to add empty object so that map can loop
over and show div. I see prop onclick function calling works but i map is not looping over it.
a little help would be appreciated.
// functional component
const listing = ({list=[]}) => (
<>
{
<div id='addPerson' onClick={() => list.push({})}>Add person</div>}
{list.map((element, index) => (
<div key={index} className='listItems'>
<p>list name</p>
</div>
))}
</>
);
export default listing;
// test case
it('renders list-items', () => {
const wrapper = shallow(<listing />);
wrapper.find('#addPerson').prop('onClick')();
console.log(wrapper.find('.listItems').length); // showing zero, expected 1
});
Updating List is not going to cause a re-render in your component. I am not sure where List is coming from, but I am assuming it is coming from a local state in the parent, or probably redux store. From inside your component, you will have to call a function in your parent to update the list array there.
Below is a version of your component, assuming the list in your local state. You will have to adjust the code to update the state in the parent or redux store, but the below should be enough to give you an idea of what to do. Also, don't push the element to array, as it mutates the object and will not contact re-render.
const Listing = ({list = [], addToList}) => {
return <>
{
<div id='addPerson' onClick={() => addToList({})}>Add person</div>}
{list.map((element, index) => (
<div key={index} className='listItems'>
<p>list name</p>
</div>
))}
</>
};

My Toaster component is not creating multiple toasters on multiple clicks. Reactjs

I have made a toaster component which is only rendering 1 toaster on 1 or multiple clicks, but I need a component the renders multiple toasters on multiple clicks.
This is my Toaster Component.
import React, {Component} from 'react'
import '../stylesheets/adminlte.css'
ToastMsg = (props) => (
<div className=" snackbar" key={props.idx}>
<div className="card-header">
<h3 className="card-title">Toast</h3>
</div>
<div className="card-body">{props.message}</div>
<div className="card-footer"/>
</div>
)
createtoaster = () => {
if (this.state.show) {
return this
.state
.message
.map((msg, idx) => <ToastMsg idx={idx} message={msg}/>)
} else {
return null;
}
}
render() {
return (
<div className="col-md-2 offset-md-9">
<button className="btn btn-primary" onClick={this.handleOpen}></button>
{this.createtoaster()}
</div>
)
}
I am providing this.state.message from another component and passsing it via props. I cannot use any Library as per the requirement so if anyone can help me with this, It is appreciated. Also feel free to point out any mistakes in my code.
missing array element 'picker': < div className="card-body">{this.state.message [i] }
I would use map, too ... with key property for each item.
Are you sure you're receiving array with more elements ?

Dynamically style a React element

I am trying to dynamically style a React element: In the nav bar, I would like to make the font color of the <div> displaying the current page to be different from the other <div>s representing other pages. I have passed into my <NavBar> component's props the params representing the current page.
From this information, I have figured out a way to achieve what I am trying to do: I store the <div>s representing the page links in an object and wrap the selected page in another <div> carrying a 'selected'class name.
However, I could envision scenarios where this solution would disrupt styling in place since it adds a wrapper element and classes within the wrapper element would take precedence over the 'selected' class.
Does anyone know a better way? I have posted my solution and the context below:
export default class NavBar extends React.Component {
constructor(props) {
super(props);
}
render() {
const pages = {
my_subscribed_docs:
<div className='nav__row2-item'>Documents I'm Subscribed To</div>,
my_created_docs:
<div className='nav__row2-item'>Documents I've Created</div>,
new_doc:
<div className='nav__row2-item'>
<div className="plus-icon">+</div>
<div className='nav__row2-text_left-of-icon'>New Document</div>
</div>,
};
const currentPage = this.props.path.slice(1);
pages[currentPage] =
<div className='nav__row2-item--selected'>{pages[currentPage]}</div>;
debugger;
return (
<nav>
<div className="nav__row1">
<div className="nav__logo">Worksheet Generator</div>
<div style={{cursor: 'pointer'}} onClick={this.props.logout}>
Logout
</div>
</div>
<div className="nav__row2" >
{ Object.values(pages).map( page => (
<div key={shortid.generate()}>{page}</div>)
) }
</div>
</nav>
);
}
}
If you want to dynamically add a class to your component, I recommend using classnames library. This is pretty much the way to do it when using external stylesheets.

Calling a function for ALL child components

I have 3 components. They parent layout, a select box, and a panel this is generated x times from some data.
<Layout>
<Dropdown>
<Panel>
<Panel>
<Panel>
I'm trying to make it so when the select value changes, the contents of each panel changes. The changes are made by doing some math between the new select value, and data that is stored in the panel component. Each panel has different data.
Layout.js
updateTrueCost(selected){
this.refs.panel.setTrueCost
}
render(){
return (
<div>
<div class="row">
Show me the true cost in
<CurrencyDrop currencyChange = {(e) => this.updateTrueCost(e)} data = {this.state.data} />
</div>
<div class="row">
{this.state.data.map((item, index) => (
<Panel ref="panel" key = {index} paneldata= {item} />
))}
</div>
</div>
);
}
Panel.js
setTrueCost(selected){
//Do some math
this.setState({truecost: mathresult})
}
render(){
return(
<div>
{this.state.truecost}
</div>
)
}
CurrencyDrop.js
onHandelChange(e){
this.props.currencyChange(e);
}
render(){
return(
<Select
onChange={this.onHandelChange.bind(this)}
options={options} />
)
}
The current result is only the last panel updates when the select changes. I'm guessing I'm doing something wrong with the ref handling, but I must not be searching the right terms because I can't find any related questions.
Instead of calling ref's method use React build-in lifecycle methods.
class Panel extends React.Component {
componentWillReceiveProps (newProps) {
// compare old and new data
// make some magic if data updates
if (this.props.panelData !== newProps.panelData) {
this.setState({trueCost: someMath()});
}
}
render () {
return <div>{this.state.trueCost}</div>
}
}
Then just change input props and all data will be updated automatically.

Resources