Passing props inorder to use the string value - javascript

I have the following functional component and de-structuring the parameter props:
const MyTimes = ({ myWindowGroup, name, fieldArrayName }) => (
<FieldArray
name={name}
render={(arrayHelpers) => (
<React.Fragment>
{myWindowGroup.fieldArrayName.map((myTime, index) => (
and I am calling the component with the following props:
<MyTimes
myWindowGroup={myWindowGroup}
fieldArrayName={"myTimes"}
name={`myWindowGroups.${index}.myTimes`}
/>
My question is as I am new to React and that is, how can I pass/use the fieldArrayName={"myTimes"} string value of myTimes into the MyTime component above so that I can replace the value of fieldArrayName.map to be myTimes.map ?
I've tried it the way it is and not working.

Use dynamic keys. See Bracket Notation.
myWindowGroup[fieldArrayName].map(....
const myWindowGroup = {
myTimes: ['This is the value array you want'],
foo: [],
};
console.log(myWindowGroup['myTimes']);
console.log(myWindowGroup['foo']);

You can just do
{myWindowGroup[fieldArrayName].map((myTime, index) => (

As I understand your question correctly, you can achieve desired output by following
const MyTimes = ({ myWindowGroup, name, fieldArrayName }) => (
<FieldArray
name={name}
render={(arrayHelpers) => (
<React.Fragment>
{myWindowGroup[fieldArrayName].map((myTime, index) => (
// your logic here
))}

Related

Javascript Object destructuring syntax confusion [duplicate]

I recently came across this piece of code on a website
const List = ({ items }) => (
<ul className="list">
{items.map(item => <ListItem item={item} />)}
</ul>
);
Why have they wrapped the items in curly braces and is it a prop
This is called a "destructuring". Actually, you're passing an object as an argument to the function, but the destructuring uses only the named properties of the object.
const destructuring = ({ used }) => console.log(used);
const properties = {
unused: 1,
used: 2,
};
destructuring(properties); // 2
You can even use it for creating variables.
const properties = {
name: 'John Doe',
age: 21,
};
const { name, age } = properties;
console.log(name, age); // John Doe 21
I'm a newbie to React, but I think yes, items is a prop, and passing {items} as an argument destructures the props object, and thus the function uses only the prop items, in order to simplify the code. This way you can use items in the functional component, instead of props.items. For example, I tested a similar situation in the following code. Using destructuring looks like this:
const ListItem = ({content}) => (
<li>{content}</li>
);
...
<ListItem key={index} content={content} />
Whereas if you used props it would look like this:
const ListItem = (props) => (
<li>{props.content}</li>
);
...
<ListItem key={index} content={content} />
So for your example, using props would look like this:
const List = (props) => (
<ul className="list">
{props.items.map(item => <ListItem item={item} />)}
</ul>
);
Meanwhile, destructuring allows you to simplify to items, rather than props.items which is what was being done in your original code:
const List = ({ items }) => (
<ul className="list">
{items.map(item => <ListItem item={item} />)}
</ul>
);
Cheers!
--Omar

Map on props of ReactJS Redux

I started my learning path few months ago (html, css, js) and I have a question for an issue that I have with react (just started learning it).
I have an error that says : data.map is not a function
I want to loop trough my array of objects with map, and dispatch the props (title, answer) to the child for each loop, to make a list of different FaqComponent having each the {title and answer}
const data = useSelector(state => ({
...state.homePage.list
}))
console.log(data);
return (
<div>
{data.map((title, answer) => (
<FaqComponent
title={title}
answer={answer}
/>
))}
</div>
);
}
export default ...;
Thanks for your replies
You're using an object {} instead of an array [] syntax.
Try with:
const data = useSelector(state => ([
...state.homePage.list
]));
You should declare "data"s type, if it is an array so your function should be like :
const data = useSelector(state => ([
...state.homePage.list
]))
console.log(data);
return (
<div>
{(data && data.length > 0) ? data.map((item, i) => (
<FaqComponent
title={item.title}
answer={item.answer}
key={i}
/>))
: <div>No Result!...</div>}
</div>
);
}
export default ...;

React Native useState onChangeText

Hi I'm wondering why this code works,
Sorry for the sintax errors, this is an Example. My question is why memberIpAssignments is taking ip value?. I don't get it if I'm no passing ip into setMemberIpAssignments(arr =>[...arr]) but still takes that's value and updating the state.
setMemberIpAssignments(arr =>[...arr]), this state shouldn't change at all, because I'm no giving ip value. But it does change taking ip value.
if someone can explain to me I'll be grateful.
I'm new at react-native
export const zeroTierNetworkMembersUpdateScreen = ({ route }) => {
const { ipAssignments } = ["192.168.0.1","192.168.1.1"];
const [memberIpAssignments, setMemberIpAssignments] =(ipAssignments);
return (
<View style={styles.viewSet}>
{memberIpAssignments.map((eachIpAssignments, index) => {
return (
<Input
key={index}
placeholder={"ipAssignments"}
keyboardType={"default"}
value={eachIpAssignments}
onChangeText={(value) => {
var ip = ipAssignments;
ip[index] = value;
setMemberIpAssignments(arr =>[...arr]);
}}
/>
);
})}
</View>
);
};
I think I've confirmed my suspicions that you are in fact mutating an object reference that you've stored in local component state.
export const zeroTierNetworkMembersUpdateScreen = ({ route }) => {
// (1) ipAssignments array reference
const ipAssignments = ["192.168.0.1", "192.168.1.1"];
// (2) memberIpAssignments references ipAssignments
const [memberIpAssignments, setMemberIpAssignments] = useState(ipAssignments);
return (
<View style={styles.viewSet}>
{memberIpAssignments.map((eachIpAssignments, index) => {
return (
<Input
key={index}
placeholder={"ipAssignments"}
keyboardType={"default"}
value={eachIpAssignments} // (3) value from memberIpAssignments
onChangeText={(value) => {
// (4) ip references ipAssignments & memberIpAssignments
var ip = ipAssignments;
// (5) element mutation!!
ip[index] = value;
// (6) state update to trigger rerender
setMemberIpAssignments(arr => [...arr]);
}}
/>
);
})}
</View>
);
};
As far as I can tell the mutation happens exactly once since initially everything is reference the original ipAssignments array. Upon updating state though, arr => [...arr] is returning a new array reference for memberIpAssignments the references back to ipAssignments is broken.
You should really be using a functional state update to "edit" the ip entry any way. Consider the following:
export default function App() {
const ipAssignments = ['192.168.0.1', '192.168.1.1'];
const [memberIpAssignments, setMemberIpAssignments] = React.useState(
ipAssignments
);
return (
<View>
{memberIpAssignments.map((eachIpAssignments, index) => {
return (
<TextInput
key={index}
placeholder={'ipAssignments'}
keyboardType={'default'}
value={eachIpAssignments}
onChangeText={(value) => {
setMemberIpAssignments((arr) =>
arr.map((el, i) => (i === index ? value : el))
);
}}
/>
);
})}
</View>
);
}
Expo Snack

alternative to innerRef when using hooks

I am converting class based components to react hooks. I got confused on using the ref parts. Because, the way I am using it complains me that The "innerRef" API has been removed in styled-components v4 in favor of React 16 ref forwarding, use "ref" instead like a typical component..
How do i make it work when using hooks?
const Tabs = ({activeTab, children}) => {
const [tabsElements, setTabsElements] = useState([])
return (
<TabsContext.TabProvider activeTab={activeTab}>
<TabsContext.TabConsumer>
{value => (
<ReactTabs>
<TabsContainer>
<ListTabs>
{value.context.tabs.map(tab => (
<TabTitleItem
key={tab.id}
onClick={value.context.onClick(tab)}
id={tab.id}
innerRef={tabElement => {
if (!tabsElements[tab.id]) {
setTabsElements(tabElements => ({
...tabElements,
[tab.id]: tabElement,
}))
}
}}
isActiveTab={value.context.activeTab.id === tab.id}
>
<TabAnchorItem>{tab.title}</TabAnchorItem>
</TabTitleItem>
))}
</ListTabs>
<ActiveTabBorder
activeTabElement={tabsElements[value.context.activeTab.id]}
/>
</TabsContainer>
{children}
</ReactTabs>
)}
</TabsContext.TabConsumer>
</TabsContext.TabProvider>
)
}
Here is the demo
https://codesandbox.io/s/z3moq8662p
First of all you cannot update state within the ref callback method. Secondly you simply need to pass ref instead of innerRef to the TabTitleItem component since it internally handles ref using forwardRef
const Tabs = ({ activeTab, children }) => {
const [tabsElements, setTabsElements] = useState([]);
const tabElements = useRef({});
return (
<TabsContext.TabProvider activeTab={activeTab}>
<TabsContext.TabConsumer>
{value => (
<ReactTabs>
<TabsContainer>
<ListTabs>
{console.log("value", value.context)}
{value.context.tabs.map(tab => (
<TabTitleItem
key={tab.id}
onClick={value.context.onClick(tab)}
id={tab.id}
ref={tabElement => {
tabElements.current[tab.id] = tabElement;
}}
isActiveTab={value.context.activeTab.id === tab.id}
>
<TabAnchorItem>{tab.title}</TabAnchorItem>
</TabTitleItem>
))}
</ListTabs>
<ActiveTabBorder
activeTabElement={tabsElements[value.context.activeTab.id]}
/>
</TabsContainer>
{children}
</ReactTabs>
)}
</TabsContext.TabConsumer>
</TabsContext.TabProvider>
);
};
Working demo

Redux form - passing a function as a property to a field array gives undefined

I am trying to pass a function as a property from a parent component to a child redux-form fieldArray component. This is the container component with the function:
constructor(props) {
super(props);
this.removePeriodCallback = this.removePeriodCallback.bind(this);
}
removePeriodCallback(periodeId) {
const { formPrefix, periods} = this.props;
this.props.reduxFormChange(
`${formPrefix}.InfoPanel`, 'periods',
periods.filter((e, i) => i === periodeId)
.sort((a, b) => a.fom > b.fom),
);
}
And I am passing it to a child component like this:
<FieldArray
name="periods"
component={Periods}
props={{ removePeriodCallback: this.removePeriodCallback }}
/>
And in the child component I have tried to access the function like this:
export const Periods= ({ fields }) => (
<div>
{fields.map((fieldId, index) => {
const toDate = fields.get(index).tom;
const fromDate = fields.get(index).fom;
const removePeriodCallback = this.props.removePeriodCallback;
return (
<Row key={fieldId}>
<Column>
<div>
<UttakPeriodeType
toDate ={toDate }
fromDate ={fromDate }
removePeriodCallback={removePeriodCallback}
/>
I have also tried to deconstruct it inside arguments of the component:
export const Periods= ({ fields, removePeriodCallback }) => (
<div>
{fields.map((fieldId, index) => {
const toDate = fields.get(index).tom;
const fromDate = fields.get(index).fom;
return (
<Row key={fieldId}>
<Column>
<div>
<UttakPeriodeType
toDate ={toDate }
fromDate ={fromDate }
removePeriodCallback={removePeriodCallback}
/>
But, both time I have got undefined when I have tried to use the removePeriodCallback
What am I doing wrong, how should I fix this?
Your deconstructed approach is the way to go. I tried with the redux form example and the somefunction in my below code worked, the function got passed
<FieldArray name="members" component={renderMembers} props={{ someFunction }}/>
const renderMembers = ({ fields, someFunction }) => (
{fields.map((member, index) => (
<li key={index}>
<button
type="button"
title="Remove Member"
onClick={() => someFunction()}
/>
you have to check the UttakPeriodeType component to which you are passing your the function.

Categories