React.FC call with multiple parameter - javascript

I am trying to call the function with three parameter but its not working.
Here is the React.FC:
const FormStructure: React.FC<{ record: ModelClass, question: Array<ModelClass>, dropdownItems: Array<ModelTypeClass> }> = ({
record, question, dropdownItems,
}) => {
...
}
and this is the function call:
return (
<Modal
visible={this.state.modalVisible}
onCancel={() => this.setState({ modalVisible: false })}
>
{FormStructure(record, this.state.question, this.state.dropdownItems)}
</Modal>
)
Following Error Message:
"Expected 1-2 arguments, but got 3"

Since FormStructure is a component, you shouldn't be calling it as a function. You should instead create a JSX element:
<Modal
visible={this.state.modalVisible}
onCancel={() => this.setState({ modalVisible: false })}
>
<FormStructure
record={record}
question={this.state.question}
dropdownItems={this.state.dropdownItems}
</FormStructure>
</Modal>
If, hypothetically, you wanted to call it as a function (again, you shouldn't do that since this is a component), the way to conform to the type definition is to pass in an object with three properties:
FormStructure({
record: record,
question: this.state.question,
dropdownItems: this.state.dropdownItems,
});

FormStructure is a Functional Component, so you better render it with the following syntax (JSX):
return (
<Modal
visible={this.state.modalVisible}
onCancel={() => this.setState({ modalVisible: false })}
>
<FormStructure record={record} question={this.state.question} dropdownItems={this.state.dropdownItems)} />
</Modal>
)

Related

Questions about antd's unique key and component structure

I'm working on a project using react, next.js, antd.
However, the following error occurred:
Warning: Each child in a list should have a unique "key" prop.
We know that the following error occurs because the list's child element does not have a unique key.
So, I tried to fix the code where the error occurred by using the following methods, but it was not resolved.
const BoardList = () => {
const { boardPosts } = useSelector((state) => state.user);
return (
<section>
<List
itemLayout="vertical"
bordered
size="large"
pagination={{
onChange: (page) => console.log(page), pageSize: 3,
}}
dataSource={boardPosts}
renderItem={(item) => (
<List.Item key={item.id}>
<BoardCard post={item} />
</List.Item>
)}
/>
</section>
)
};
------------------------------
try 0.
<List.Item>
<BoardCard post={item} key={item.id} />
</List.Item>
try 1.
<List.Item key={item.id}>
<BoardCard post={item} />
</List.Item>
try 2.
renderItem={(item, i) => (
<List.Item key={i}>
<BoardCard post={item} />
</List.Item>
try 3.
<List.Item>
<div key={item.id}>
<BoardCard post={item} />
</div>
</List.Item>
try 4.
<div key={item.id}>
<List.Item>
<BoardCard post={item} />
</List.Item>
</div>
So I start to doubt whether the above problem is a problem with the component structure.
The component where the problem occurred consists of the following three components.
// pages/profile
import React from 'react';
import NicknameEditForm from './NicknameEditForm';
import MyScrap from './MyScrap';
import MyBoard from './MyBoard';
const MyInfo = () => {
return (
<section>
<NicknameEditForm /> // A component that changes a member's nickname
<MyScrap /> // Gets the post that has been liked from the POST table.
<MyBoard /> // I get the post I wrote from the POST table.
</section>
)
};
export default MyInfo;
// MyScrap.js
const { likedPosts } = useSelector((state) => state.post);
// MyBoard.js
const { boardPosts } = useSelector((state) => state.post);
Also, MyScrap and MyBoard components receive the following data from the backend and use it.
// likedPosts used in MyScrap component
likedPosts = [{id: 1, title: 'title1',.....}, [...] ...]
// boardPosts used in MyBoard component
boardPosts = [{id: 1, title: 'title1',.....}, [...] ...]
So, I wonder if the following problem occurred because the key values of MyScrap component and MyBoard component overlap due to the following structure on one page or if there is another reason.
Try using rowKey in List component. You can check the example here
const BoardList = () => {
const { boardPosts } = useSelector((state) => state.user);
return (
<section>
<List
itemLayout="vertical"
bordered
size="large"
rowKey={(item) => item.id}
pagination={{
onChange: (page) => console.log(page), pageSize: 3,
}}
dataSource={boardPosts}
renderItem={(item) => (
<List.Item>
<BoardCard post={item} />
</List.Item>
)}
/>
</section>
)
};

Getting the element that was clicked in functional component in React

I'm new to React and can't get the clicked element.
"this" in functional component doesn't work
function Test(data) {
function getElement() {
}
return (
<div>
{data.map((option: any, index: any) => (
<Text
key={index}
onClick={() => getElement()}
>
{option}
</Text>
))}
</div>
)
}
there are several elements in the data that I want to switch one by one, changing the class 'active', but it is not possible to get the element that was clicked
Be sure to pass the event to your click handler:
function Test(data) {
const handleClick = e => {
const el = e.target
console.log(el)
}
return (
<div>
{data.map((option: any, index: any) => (
<Text
key={index}
onClick={handleClick}
>
{option}
</Text>
))}
</div>
)
}

How to pass a function to a different screen

I have 2 screens that I need to share a function ie
//ScreenOne.js
import ScreenTwo from "./ScreenTwo"
...{...
function handlePress(){
Alert.alert(
"",
"Clicked",
[{text: "ok", onPress: ()=>null}]
)
}
return(
<>
<FlatList
data={source}
renderItem={({ item }) => <ScreenTwo item={item} />} />
<Button onPress={handlePress}/>
</>
)
...}...
//ScreenTwo.js
...{...
return(
<>
<Text>{...}</Text>
<Button onPress={handlePress}/>)
</>
...}...
I'm working with functional components. Most of the materials I read only talk of passing data and not methods/functions to other screens. Using this example how can I call the handlePress from ScreenOne to Two...
I'm assuming you are talking about sharing the handlePress function.
You can pass a function in the props:
<ScreenTwo item={item} handlePress={handlePress}/>
And then use it in ScreenTwo
const ScreenTwo = ({handlePress, ...rest}) => {
...
<Button onPress={handlePress}/>)
...
}

React: Trasform submit button on click

In my render I have:
render(){
return (
//.....
<this.Content>
//...
in Content I have all the parts that I show to user and at the end I have:
Content = props => {
return(
//..
<Submit
onSubmit={self.props.handleSubmit(values => self._onSubmit(values))}
/>
)}
Now my problem is when the submit button has clicked I would to change it with:
<Spinner animation="border" variant="primary" />
How can I do?
EDIT.
constructor(props){
super(props);
this.state = {
wasButtonClicked: false,
}
Content = props => {
return(
//
{this.state.wasButtonClicked == true ? <Spinner animation="border" variant="primary" /> : <Submit onSubmit={self.props.handleSubmit(values => {this.setState({wasButtonClicked: true}),self._onSubmit(values)})} />}
/>
}
render() {
return(
//
this.state.HasEmail === true
?
<this.Content />
:
If your using JSX you can:
Create a state wasButtonClicked and initiate it with false.
onclick of the button setState wasButtonClicked to true
Insted of rendering the button call {this.renderItem()}
Create the function:
renderItem = () => {
return this.state.wasButtonClicked ? <Spinner animation="border" variant="primary" /> : <YourBUttonELement/>
}
Steps to implement with your code in a simple language
You have added wasButtonClicked in this.state.
Use ternary condition in the return of your Content function. If wasButtonClicked is true then return <Spinner animation="border" variant="primary" />, on false return Submit button.
OnClick of your submit button setState wasButtonClicked to true.
setState wasButtonClicked to false whenever your required operation completed.
Style the Spinner wrap it inside a div or way suitable to look similar to the button
EDITED
Use this instead of your Content function
Content = props => {
return (
this.state.wasButtonClicked
? <Spinner animation="border" variant="primary" />
: <Submit onSubmit={() => self.props.handleSubmit(values => {
this.setState({ wasButtonClicked: true });
self._onSubmit(values);
})} />
)
}
I don't know what is self referred to in your code is it the this keyword you are using here. I made your code syntactically correct.

Destructuring and passing in full object simultaenously

I have a simple React component:
const FullContainer = ({
backgroundColor,
children,
}) => (
<Container
backgroundColor={backgroundColor}
>
{children}
</Container>
);
I'm currently destructing the only two properties I expect my component to use, but I'd also like to pass in props and spread it in as well:
const FullContainer = (props, {
backgroundColor,
children,
}) => (
<Container
backgroundColor={backgroundColor}
{...props}
>
{children}
</Container>
);
Oddly enough, this breaks my page with no errors. I must be doing something wrong. Is my syntax wrong?
You can make use of rest spread syntax that provides the remaining properties which aren't destructured as an array like
const FullContainer = ({
backgroundColor,
children,
...props
}) => (
<Container
backgroundColor={backgroundColor}
{...props}
>
{children}
</Container>
);

Categories