I am learning and practicing hooks useState in react js. For example, when declaring a state variable like this,
const [votes, setVotes] = useState(0)
I know that the 0 value in useState() means that votes is initialized with starting value of 0. However, advancing a little bit, like this,
const [votes, setVotes] = useState(() => Array(fruits.length).fill(0))
Given an array,
const fruits = ["kiwi", "banana", "mango", "apple", "durian"]
I am a little confused with the Array in the second state variable wrapping fruits.length, why do we have to wrap it with Array ? fruits is already an array. And just to make sure that I understand, the .fill(0) means that we will initialize every element in the array fruit with 0? Am I right ? To give a context, I have an array fruits and two buttons, one is to vote, and the other is to select randomly the next fruit. Every time I vote, the vote will increase and when I click the other button, random fruits will be displayed and the vote will be 0 for fruits that haven't got voted. This is the vote button code,
const handleVotes = () => {
setVotes((votes) =>
votes.map((vote, index) => index === selected ? vote + 1 : vote)
)
}
Mapping over the entire array of fruits is rather inefficient. We can use a Map which allows us to create a mapping between fruits and their votes. This allows us to update a fruit directly, without having to evaluate a condition against each element. Run the demo below and vote for your favourite!
function App({ fruits }) {
const [selected, setSelected] = React.useState(fruits[0])
const [votes, setVotes] = React.useState(() => new Map)
const select = fruit => event => {
setSelected(fruit)
}
const vote = event => {
setVotes(vs =>
new Map(vs).set(selected, (vs.get(selected) || 0) + 1)
)
}
return <div>
{fruits.map(f =>
<button
onClick={select(f)}
className={selected == f ? "selected" : ""}
children={f}
/>
)}
<button onClick={vote} children="vote" />
<pre>{JSON.stringify(Object.fromEntries([...votes]))}</pre>
</div>
}
ReactDOM.render(<App fruits={["๐ฅ","๐","๐"]} />, document.body)
.selected { border-color: teal; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js"></script>
Array(array.length).fill(0) is a JavaScript expression that creates a new array filled with a specified value. The expression creates an array with the length equal to the length of the array variable passed as an argument. The .fill(0) method is then used to fill the entire array with the value 0.
Here's an example:
const array = [1, 2, 3, 4, 5];
const newArray = Array(array.length).fill(0);
console.log(newArray);
// Output: [0, 0, 0, 0, 0]
In this example, array is an array with 5 elements, so Array(array.length).fill(0) creates a new array with 5 elements, all filled with the value 0.
I hope this helps!
Related
The story is, I should be able to put Bob, Sally and Jack into a box. I can also remove either from the box. When removed, no slot is left.
people = ["Bob", "Sally", "Jack"]
I now need to remove, say, "Bob". The new array would be:
["Sally", "Jack"]
Here is my react component:
...
getInitialState: function() {
return{
people: [],
}
},
selectPeople(e){
this.setState({people: this.state.people.concat([e.target.value])})
},
removePeople(e){
var array = this.state.people;
var index = array.indexOf(e.target.value); // Let's say it's Bob.
delete array[index];
},
...
Here I show you a minimal code as there is more to it (onClick etc). The key part is to delete, remove, destroy "Bob" from the array but removePeople() is not working when called. Any ideas? I was looking at this but I might be doing something wrong since I'm using React.
When using React, you should never mutate the state directly. If an object (or Array, which is an object too) is changed, you should create a new copy.
Others have suggested using Array.prototype.splice(), but that method mutates the Array, so it's better not to use splice() with React.
Easiest to use Array.prototype.filter() to create a new array:
removePeople(e) {
this.setState({people: this.state.people.filter(function(person) {
return person !== e.target.value
})});
}
To remove an element from an array, just do:
array.splice(index, 1);
In your case:
removePeople(e) {
var array = [...this.state.people]; // make a separate copy of the array
var index = array.indexOf(e.target.value)
if (index !== -1) {
array.splice(index, 1);
this.setState({people: array});
}
},
Here is a minor variation on Aleksandr Petrov's response using ES6
removePeople(e) {
let filteredArray = this.state.people.filter(item => item !== e.target.value)
this.setState({people: filteredArray});
}
Simple solution using slice without mutating the state
const [items, setItems] = useState(data);
const removeItem = (index) => {
setItems([
...items.slice(0, index),
...items.slice(index + 1)
]);
}
Use .splice to remove item from array. Using delete, indexes of the array will not be altered but the value of specific index will be undefined
The splice() method changes the content of an array by removing existing elements and/or adding new elements.
Syntax: array.splice(start, deleteCount[, item1[, item2[, ...]]])
var people = ["Bob", "Sally", "Jack"]
var toRemove = 'Bob';
var index = people.indexOf(toRemove);
if (index > -1) { //Make sure item is present in the array, without if condition, -n indexes will be considered from the end of the array.
people.splice(index, 1);
}
console.log(people);
Edit:
As pointed out by justin-grant, As a rule of thumb, Never mutate this.state directly, as calling setState() afterward may replace the mutation you made. Treat this.state as if it were immutable.
The alternative is, create copies of the objects in this.state and manipulate the copies, assigning them back using setState(). Array#map, Array#filter etc. could be used.
this.setState({people: this.state.people.filter(item => item !== e.target.value);});
Easy Way To Delete Item From state array in react:
when any data delete from database and update list without API calling that time you pass deleted id to this function and this function remove deleted recored from list
export default class PostList extends Component {
this.state = {
postList: [
{
id: 1,
name: 'All Items',
}, {
id: 2,
name: 'In Stock Items',
}
],
}
remove_post_on_list = (deletePostId) => {
this.setState({
postList: this.state.postList.filter(item => item.post_id != deletePostId)
})
}
}
filter method is the best way to modify the array without touching the state.
It returns a new array based on the condition.
In your case filter check the condition person.id !== id and create a new array excluding the item based on condition.
const [people, setPeople] = useState(data);
const handleRemove = (id) => {
const newPeople = people.filter((person) => person.id !== id);
setPeople( newPeople);
};
<button onClick={() => handleRemove(id)}>Remove</button>
Not advisable:
But you can also use an item index for the condition if you don't have any id.
index !== itemIndex
This is your current state variable:
const [animals, setAnimals] = useState(["dogs", "cats", ...])
Call this function and pass the item you would like to remove.
removeItem("dogs")
const removeItem = (item) => {
setAnimals((prevState) =>
prevState.filter((prevItem) => prevItem !== item)
);
};
your state variable now becomes:
["cats", ...]
Another way of doing it is by using useState hook. Check docs: https://reactjs.org/docs/hooks-reference.html#functional-updates It states: Unlike the setState method found in class components, useState does not automatically merge update objects. You can replicate this behavior by combining the function updater form with object spread syntax as shown below or use useReducer hook.
const [state, setState] = useState({});
setState(prevState => {
return {...prevState, ...updatedValues};
});
Some answers mentioned using 'splice', which did as Chance Smith said mutated the array. I would suggest you to use the Method call 'slice'
(Document for 'slice' is here) which make a copy of the original array.
Just filter out deleted item and update the state with remaining items again,
let remainingItems = allItems.filter((item) => {return item.id !== item_id});
setItems(remainingItems);
const [people, setPeople] = useState(data);
const handleRemove = (id) => {
const newPeople = people.filter((person) => { person.id !== id;
setPeople( newPeople );
});
};
<button onClick={() => handleRemove(id)}>Remove</button>
It's Very Simple
First You Define a value
state = {
checked_Array: []
}
Now,
fun(index) {
var checked = this.state.checked_Array;
var values = checked.indexOf(index)
checked.splice(values, 1);
this.setState({checked_Array: checked});
console.log(this.state.checked_Array)
}
removePeople(e){
var array = this.state.people;
var index = array.indexOf(e.target.value); // Let's say it's Bob.
array.splice(index,1);
}
Redfer doc for more info
Almost all the answers here seem to be for class components, here's a code that worked for me in a functional component.
const [arr,setArr]=useState([]);
const removeElement=(id)=>{
var index = arr.indexOf(id)
if(index!==-1){
setArr(oldArray=>oldArray.splice(index, 1));
}
}
If you use:
const[myArr, setMyArr] = useState([]);
for add:
setMyArr([...myArr, value]);
and for remove:
let index = myArr.indexOf(value);
if(index !== -1)
setPatch([...myArr.slice(0, index), ...myArr.slice(index, myArr.length-1)]);
Removing an element with a certain value
//
Note filter function always returns a new array.
const people = ["Bob", "Sally", "Jack"]
const removeEntry = (remove) => {
const upDatePeople = people.filter((Person) =>{
return Person !== remove
});
console.log(upDatePeople)
//Output: [ 'Sally', 'Jack' ]
}
removeEntry("Bob");
You forgot to use setState. Example:
removePeople(e){
var array = this.state.people;
var index = array.indexOf(e.target.value); // Let's say it's Bob.
delete array[index];
this.setState({
people: array
})
},
But it's better to use filter because it does not mutate array.
Example:
removePeople(e){
var array = this.state.people.filter(function(item) {
return item !== e.target.value
});
this.setState({
people: array
})
},
const [randomNumbers, setRandomNumbers] = useState([111,432,321]);
const numberToBeDeleted = 432;
// Filter (preferred)
let newRandomNumbers = randomNumbers.filter(number => number !== numberToBeDeleted)
setRandomNumbers(newRandomNumbers);
//Splice (alternative)
let indexOfNumberToBeDeleted = randomNumbers.indexOf(numberToBeDeleted);
let newRandomNumbers = Array.from(randomNumbers);
newRandomNumbers.splice(indexOfNumberToBeDeleted, 1);
setRandomNumbers(newRandomNumbers);
//Slice (not preferred - code complexity)
let indexOfNumberToBeDeleted = randomNumbers.indexOf(numberToBeDeleted);
let deletedNumber = randomNumbers.slice(indexOfNumberToBeDeleted, indexOfNumberToBeDeleted+1);
let newRandomNumbers = [];
for(let number of randomNumbers) {
if(deletedNumber[0] !== number)
newRandomNumbers.push(number);
};
setRandomNumbers(newRandomNumbers);
The story is, I should be able to put Bob, Sally and Jack into a box. I can also remove either from the box. When removed, no slot is left.
people = ["Bob", "Sally", "Jack"]
I now need to remove, say, "Bob". The new array would be:
["Sally", "Jack"]
Here is my react component:
...
getInitialState: function() {
return{
people: [],
}
},
selectPeople(e){
this.setState({people: this.state.people.concat([e.target.value])})
},
removePeople(e){
var array = this.state.people;
var index = array.indexOf(e.target.value); // Let's say it's Bob.
delete array[index];
},
...
Here I show you a minimal code as there is more to it (onClick etc). The key part is to delete, remove, destroy "Bob" from the array but removePeople() is not working when called. Any ideas? I was looking at this but I might be doing something wrong since I'm using React.
When using React, you should never mutate the state directly. If an object (or Array, which is an object too) is changed, you should create a new copy.
Others have suggested using Array.prototype.splice(), but that method mutates the Array, so it's better not to use splice() with React.
Easiest to use Array.prototype.filter() to create a new array:
removePeople(e) {
this.setState({people: this.state.people.filter(function(person) {
return person !== e.target.value
})});
}
To remove an element from an array, just do:
array.splice(index, 1);
In your case:
removePeople(e) {
var array = [...this.state.people]; // make a separate copy of the array
var index = array.indexOf(e.target.value)
if (index !== -1) {
array.splice(index, 1);
this.setState({people: array});
}
},
Here is a minor variation on Aleksandr Petrov's response using ES6
removePeople(e) {
let filteredArray = this.state.people.filter(item => item !== e.target.value)
this.setState({people: filteredArray});
}
Simple solution using slice without mutating the state
const [items, setItems] = useState(data);
const removeItem = (index) => {
setItems([
...items.slice(0, index),
...items.slice(index + 1)
]);
}
Use .splice to remove item from array. Using delete, indexes of the array will not be altered but the value of specific index will be undefined
The splice() method changes the content of an array by removing existing elements and/or adding new elements.
Syntax: array.splice(start, deleteCount[, item1[, item2[, ...]]])
var people = ["Bob", "Sally", "Jack"]
var toRemove = 'Bob';
var index = people.indexOf(toRemove);
if (index > -1) { //Make sure item is present in the array, without if condition, -n indexes will be considered from the end of the array.
people.splice(index, 1);
}
console.log(people);
Edit:
As pointed out by justin-grant, As a rule of thumb, Never mutate this.state directly, as calling setState() afterward may replace the mutation you made. Treat this.state as if it were immutable.
The alternative is, create copies of the objects in this.state and manipulate the copies, assigning them back using setState(). Array#map, Array#filter etc. could be used.
this.setState({people: this.state.people.filter(item => item !== e.target.value);});
Easy Way To Delete Item From state array in react:
when any data delete from database and update list without API calling that time you pass deleted id to this function and this function remove deleted recored from list
export default class PostList extends Component {
this.state = {
postList: [
{
id: 1,
name: 'All Items',
}, {
id: 2,
name: 'In Stock Items',
}
],
}
remove_post_on_list = (deletePostId) => {
this.setState({
postList: this.state.postList.filter(item => item.post_id != deletePostId)
})
}
}
filter method is the best way to modify the array without touching the state.
It returns a new array based on the condition.
In your case filter check the condition person.id !== id and create a new array excluding the item based on condition.
const [people, setPeople] = useState(data);
const handleRemove = (id) => {
const newPeople = people.filter((person) => person.id !== id);
setPeople( newPeople);
};
<button onClick={() => handleRemove(id)}>Remove</button>
Not advisable:
But you can also use an item index for the condition if you don't have any id.
index !== itemIndex
This is your current state variable:
const [animals, setAnimals] = useState(["dogs", "cats", ...])
Call this function and pass the item you would like to remove.
removeItem("dogs")
const removeItem = (item) => {
setAnimals((prevState) =>
prevState.filter((prevItem) => prevItem !== item)
);
};
your state variable now becomes:
["cats", ...]
Another way of doing it is by using useState hook. Check docs: https://reactjs.org/docs/hooks-reference.html#functional-updates It states: Unlike the setState method found in class components, useState does not automatically merge update objects. You can replicate this behavior by combining the function updater form with object spread syntax as shown below or use useReducer hook.
const [state, setState] = useState({});
setState(prevState => {
return {...prevState, ...updatedValues};
});
Some answers mentioned using 'splice', which did as Chance Smith said mutated the array. I would suggest you to use the Method call 'slice'
(Document for 'slice' is here) which make a copy of the original array.
Just filter out deleted item and update the state with remaining items again,
let remainingItems = allItems.filter((item) => {return item.id !== item_id});
setItems(remainingItems);
const [people, setPeople] = useState(data);
const handleRemove = (id) => {
const newPeople = people.filter((person) => { person.id !== id;
setPeople( newPeople );
});
};
<button onClick={() => handleRemove(id)}>Remove</button>
It's Very Simple
First You Define a value
state = {
checked_Array: []
}
Now,
fun(index) {
var checked = this.state.checked_Array;
var values = checked.indexOf(index)
checked.splice(values, 1);
this.setState({checked_Array: checked});
console.log(this.state.checked_Array)
}
removePeople(e){
var array = this.state.people;
var index = array.indexOf(e.target.value); // Let's say it's Bob.
array.splice(index,1);
}
Redfer doc for more info
Almost all the answers here seem to be for class components, here's a code that worked for me in a functional component.
const [arr,setArr]=useState([]);
const removeElement=(id)=>{
var index = arr.indexOf(id)
if(index!==-1){
setArr(oldArray=>oldArray.splice(index, 1));
}
}
If you use:
const[myArr, setMyArr] = useState([]);
for add:
setMyArr([...myArr, value]);
and for remove:
let index = myArr.indexOf(value);
if(index !== -1)
setPatch([...myArr.slice(0, index), ...myArr.slice(index, myArr.length-1)]);
Removing an element with a certain value
//
Note filter function always returns a new array.
const people = ["Bob", "Sally", "Jack"]
const removeEntry = (remove) => {
const upDatePeople = people.filter((Person) =>{
return Person !== remove
});
console.log(upDatePeople)
//Output: [ 'Sally', 'Jack' ]
}
removeEntry("Bob");
You forgot to use setState. Example:
removePeople(e){
var array = this.state.people;
var index = array.indexOf(e.target.value); // Let's say it's Bob.
delete array[index];
this.setState({
people: array
})
},
But it's better to use filter because it does not mutate array.
Example:
removePeople(e){
var array = this.state.people.filter(function(item) {
return item !== e.target.value
});
this.setState({
people: array
})
},
const [randomNumbers, setRandomNumbers] = useState([111,432,321]);
const numberToBeDeleted = 432;
// Filter (preferred)
let newRandomNumbers = randomNumbers.filter(number => number !== numberToBeDeleted)
setRandomNumbers(newRandomNumbers);
//Splice (alternative)
let indexOfNumberToBeDeleted = randomNumbers.indexOf(numberToBeDeleted);
let newRandomNumbers = Array.from(randomNumbers);
newRandomNumbers.splice(indexOfNumberToBeDeleted, 1);
setRandomNumbers(newRandomNumbers);
//Slice (not preferred - code complexity)
let indexOfNumberToBeDeleted = randomNumbers.indexOf(numberToBeDeleted);
let deletedNumber = randomNumbers.slice(indexOfNumberToBeDeleted, indexOfNumberToBeDeleted+1);
let newRandomNumbers = [];
for(let number of randomNumbers) {
if(deletedNumber[0] !== number)
newRandomNumbers.push(number);
};
setRandomNumbers(newRandomNumbers);
I am creating a dropdown filter to update the search results of a page using react hooks. Basically, I am passing an array with the options that the user chose from the dropdown menu. I am successfully updating the global state with the new arrays BUT my issue is useState creates a NEW array instead of merging the results with the previous state.
Above you can see, I made two calls with different filter options and the global state now holds 2 arrays. My goal is to have both arrays merged into one.
This is the function where the global state is being updated.
const Results = () => {
const [filterList, setFilterList] = useState([])
const setGlobalFilter = (newFilter) => {
let indexFilter = filterList.indexOf(newFilter);
// console.log("Top level index", indexFilter)
indexFilter ?
setFilterList([...new Set([...filterList, newFilter])]) :
setFilterList(filterList => filterList.filter((filter, i) => i !== indexFilter))
}
// console.log("TopFilterSelection:", filterList)
return (
<div>
<Filter setFilter={(filterList) => setGlobalFilter(filterList)}/>
</div>
)
}
I've been checking on using prevState like this:
...
setFilterList(prevState => [...new Set([...prevState, newFilter])]) :
...
But I don't know what I am doing wrong.
Any feedback would be much appreciated!
This happens because newFilteris an array, not a word.
Should be
setFilterList(previous => [...new Set([...previous, ...newFilter])])
Also this
let indexFilter = filterList.indexOf(newFilter);
always returns -1 if newFilteris an array (since you a sending brand new array each time), it's not a falsy value, be careful
Use the .concat method.
setFilterList(filterList.concat(newFilter))
Read more about it here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat
Let's start with my favorite JavaScript expression:
[]==[] // false
Now, let's say what the React doc says about skipping side effects:
You can tell React to skip applying an effect if certain values havenโt changed between re-renders. To do so, pass an array as an optional second argument to useEffect:
useEffect(() => {/* only runs if 'count' changes */}, [count])
Now let's consider the following component which behavior had made me scratch my head:
const App = () => {
const [fruit, setFruit] = React.useState('');
React.useEffect(() => console.log(`Fruit changed to ${fruit}`), [fruit]);
const [fruits, setFruits] = React.useState([]);
React.useEffect(() => console.log(`Fruits changed to ${fruits}`), [fruits]);
return (<div>
<p>
New fruit:
<input value={fruit} onChange={evt => setFruit(evt.target.value)}/>
<button onClick={() => setFruits([...fruits, fruit])}>Add</button>
</p>
<p>
Fruits list:
</p>
<ul>
{fruits.map(f => (<li key={f}>{f}</li>))}
</ul>
</div>)
}
ReactDOM.render(<App/>, document.querySelector('#root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
When adding 'apple', this is what is being logged in the console:
// on first render
Fruit changed to
Fruits changed to
// after each keystroke of 'apple'
Fruit changed to a
Fruit changed to ap
Fruit changed to app
Fruit changed to appl
Fruit changed to apple
// ater clicking on 'add'
Fruits changed to apple
And I don't understand the middle part. After each keystroke, fruits goes from [] to [], which are not the same in JS if they refer to different objects. Therefore, I expected some Fruits changed to to be logged. So my question is:
What is the exact object comparison process used by React to decide on whether or not to skip the effect hook?
A function which is being used to compare objects is practically a polyfill of Object.is method. You can see it here in the source code:
https://github.com/facebook/react/blob/master/packages/shared/objectIs.js
And here's a function which compares prevDeps with nextDeps within useEffect implementation:
https://github.com/facebook/react/blob/master/packages/react-reconciler/src/ReactFiberHooks.new.js#L1427
By the way, Object.is is mentioned as a comparison algorhitm in the hooks API section of the docs, under useState.
After each keystroke, fruits goes from [] to []
It seems that you're under the impression that fruits is re-assigning to a new array after each key stroke which is not the case.
It is not comparing two new arrays, it is comparing the same label, which points to the same reference in the memory in this particular point of time.
Given:
var arr = [];
We can check if arr reference has changed over time (if no mutations took place).
simple example:
var arr = [];
var arr2 = arr;
console.log('arr === arr ', arr === arr)
console.log('arr === arr2 ', arr === arr2)
arr = [];
console.log('---- After the change ----');
console.log('arr === arr ', arr === arr)
console.log('arr === arr2 ', arr === arr2)
I want to map an array of 5 items like so:
list.slice(0, 5).map((i) => {
return <div>{i}</div>
});
However, If the array only has 3 items and I want to fill the remaining items in the array with placeholders in my react component. Can I do this with .map()? to display like so:
one
two
three
placeholder
placeholder
Use Array.from() to create an array of placeholder needed to fill the missing places in the list, and combine with the original list:
const Demo = ({ list, minLength = 5 }) => (
<ul>
{[
...list,
...Array.from({ length: minLength - list.length }, () => 'placeholder')
].map((i) => <li>{i}</li>)
}
</ul>
);
const list = ['a', 'b', 'c']
ReactDOM.render(
<Demo list={list} />,
demo
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="demo"></div>
You can also use Array.from() to render the items directly:
const getLength = ({ length }, minLength) => minLength > length ? minLength : length;
const Demo = ({ list, minLength = 5 }) => (
<ul>
{Array.from({ ...list, length: getLength(list, minLength) }, o =>
<li>{o === undefined ? 'placeholder' : o}</li>
)}
</ul>
);
const list = ['a', 'b', 'c']
ReactDOM.render(
<Demo list={list} />,
demo
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="demo"></div>
You can't do what you're asking for with map alone. The other suggestions here are good, but in my opinion, it's a bit cleaner to use Array.from like this:
var list = ['one', 'two', 'three'];
var result = Array.from({length: 5}, (x, i) => i in list ? list[i] : 'placeholder');
console.log(result) // 'one', 'two', 'three', 'placeholder', 'placeholder'
This will produce an array of 5 elements regardless of whether list contains more or less than 5, so you can get rid of your call to slice. You'd use this in react like this:
Array.from({length: 5}, (x, i) => {
return <div>{i in list ? list[i] : 'placeholder'}</div>
})
No. As the Array.prototype.map docs mention, the function returns a new array with the results of calling a provided function on every element in the calling array. Since list list only contains 3 elements, the map function will only iterate over those 3 elements.
However, if you wanted to add placeholders to the end of the array you could do something like (or a variety of other options):
const results = []
for (let i = 0; i < 5; i++) {
results.push(list[i] || 'placeholder')
}
For example, with the following list: const list = ["a", "b", "c"], the output of the above code would be ["a", "b", "c", "placeholder", "placeholder"].
In the context of a React component you could map over results, and wrap each item in the array with a div, as you had originally intended.
Not with .map alone, no - but, you could push to the sliceed array first, if its length is insufficient:
const sliced = list.slice(0, 5);
const { length } = sliced;
if (length < 5) {
sliced.push(...new Array(5 - length).fill('placeholder'));
}
sliced.map(...
No, you cannot append additional elements to an array with map(). One solution is to first check the length of the input array and pad it with additional elements if necessary. Then map() as you are already.
const list = [1, 2, 3];
list.slice(0, 5).concat(new Array(5 - list.length));
A one liner (no warranty as to efficiency):
const list5 = list.map(...).concat([placeholder, placeholder, placeholder, placeholder, placeholder]).slice(0,5);
If you are doing this a bunch of times the placeholder[] could be a constant.