React table rowProps prop doesnt log anything - javascript

[Basically, we're using this from one of our libraries. But the thing is while using it through our package the rowProps prop doesn't work]
(https://i.stack.imgur.com/fER2B.png).
import { AdvancedTable } from "ims-ui-kit";
function Table(props) {
console.log(props)
return <AdvancedTable {...props} />;
}
export default Table;
Here is another screenshot of the prop passing through the table we are using. It doesn't log anything.
[enter image description here]
<>
{alert}
<div className="content">
<ReactTable
// hasBulkActions={true}
data={data}
filterable
{...rest}
resizable={false}
columns={columns.slice()}
defaultPageSize={10}
showPaginationTop
showPaginationBottom={false}
className="-striped -highlight"
rowProps={(row) => {
onclick = () => {
console.log("hello", row);
};
}}
/>
<Modal title="Risk management">
<RiskDetail isModalOpen={isOpen} />
</Modal>
</div>
</>

Related

Create custom TabPane using react-bootstrap

I would create custom Tab Form from JSON, using React and boostrap. Using this function my code work correctly.
function DisplayForm(props) {
return(
<div className="row">
<Tabs className="mb-3">
{Array.from(new Map(Object.entries(json))).map((data) => (
<Tab eventKey={data[0]} title={data[0]}> </Tab>
))}
</Tabs>
</div>
);
}
}
data[0] is the tabName.
Now, I would create custom tab, based on json value. For example, something, like this:
function DisplayCustomTab(props) {
return(
<div className="row">
<TabContainer className="mb-3">
<TabContent>
{Array.from(new Map(Object.entries(json))).map((data) => (
<>
{(() => {
if(myCondition ) {
return(
<>
<CreateTAB data={data[0]} />
</>
)
}
})()}
</>
))}
</TabContent>
</TabContainer>
</div>
);
}
function CreateTAB(props) {
console.log("tab name: " + props.data); // this line works
return(
<TabPane eventKey={props.data} title={props.data}> </TabPane>
);
}
I using TabPane, TabContent and TabContainer because using Tab and Tabs I get following error:
component is not meant to be rendered! It's an abstract component that is only valid as a direct Child of the `Tabs` Component. For custom tabs components use TabPane and TabsContainer directly
Anyone can explain where I'm wrong? Thank you

How to access props in the component using react and typescript?

i want to access props in the react functional component using react and typescript.
I have the MainComponent which has Layout component and i pass prop isOpen to Layout component from MainComponent like in below code,
const Layout: React.FC = ({children}) => ( //how to access isOpen prop here
<>
<leftNav />
{children}
<RightNav isOpen={isOpen} />
</>
);
interface Props {
item: item;
}
function Main({ item }: Props) {
return (
<Wrapper>
<Switch>
<Route
path="/items"
render={routeProps => (
<Layout isOpen={isOpen}> //passing prop here
<Items />
</Layout>
)}
/>
</Switch>
</Wrapper>
)
}
I have tried to access it like below
interface Props {
children: any;
isOpen: boolean;
}
const Layout: React.FC = ({children, isOpen}: Props) => (
<>
<leftNav />
{children}
<RightNav isOpen={isOpen} />
</>
);
But the above throws error jsxelement is not assignable to type FC component.
could someone help me fix this. thanks.
React.FC is generic and takes a type argument for the props. You can write your layout component like this.
interface Props {
isOpen: boolean;
// if you want isOpen props to be optional
// isOpen?: boolean;
}
const Layout: React.FC<Props> = ({children, isOpen}) => (
<>
<leftNav />
{children}
<RightNav isOpen={isOpen} />
</>
);
Your main component is fine.
You need to type the props for the FC generic:
//interface Props { ... }
const Layout: React.FC<Props> = ({children, isOpen}) => (
<>
<leftNav />
{children}
<RightNav isOpen={isOpen} />
</>
);
or omit the FC altogether:
//interface Props { ... }
const Layout: ({children, isOpen}: Props) => (
<>
<leftNav />
{children}
<RightNav isOpen={isOpen} />
</>
);

multiple items inside the rightIconButton of a MaterialUI ListItem

I want to attach multiple items to the rightIconButton inside a ListItem.
I'm using Material UI v0.20 and React#15.6.2
<ListItem
rightIconButton={
<span>
<RaisedButton />
<TrashIcon />
</span>
}
/>
How can i wrap the items to avoid the warning?
Warning: Unknown prop onKeyboardFocus on span tag. Remove this prop from the element.
Try using HOC:
function Single() {
return (
<div>
<RaisedButton>Hello</RaisedButton>
<RaisedButton>wORLD</RaisedButton>
</div>
);
}
function App() {
return (
<MuiThemeProvider>
<List>
<ListItem rightIconButton={<Single />} />
</List>
</MuiThemeProvider>
);
}
A custom component will help to remove the warning:
function GroupedButtons(props) {
return (
<span>
<RaisedButton>Hello</RaisedButton>
<RaisedButton>WORLD</RaisedButton>
</span>
)
}
...
function App() {
...
<ListItem
rightIconButton={
<GroupedButtons />
}
/>
Working example:

react-popper: re-position using scheduleUpdate

I'm using React-popper to show a date picker element after clicking a button.
JSX
<Manager>
<Reference>
{({ ref }) => (
<button ref={ref} onClick={this.onDateRangeBtnClick}>click to show</button>
)}
</Reference>
{ReactDOM.createPortal(
<Popper placement="auto-end" >
{({ ref, style, placement, arrowProps, scheduleUpdate }) => (
<div className={`dayPickerOverlay ${this.state.showDatePicker ? "" : "hidden"}`} ref={ref} style={style} data-placement={placement}>
<DateRangePicker />
</div>
)}
</Popper>,
document.querySelector('#root')
)}
</Manager>
When onDateRangeBtnClick is called after the button was clicked, I want to re-position the Popper element by calling scheduleUpdate method, but I do not know how to approach this.
How can I expose that specific scheduleUpdate to be called within the onDateRangeBtnClick or alternatively how can I conditionally call a function (scheduleUpdate for this matter) within JSX itself?
I would split the popper part into its own component and take advantage of the React lifecycle hooks.
Inside componentDidUpdate you can check if the open state changed, and trigger the scheduleUpdate accordingly.
// PopperElement.js
export default class PopperElement extends React.Component {
componentDidUpdate(prevProps) {
if (this.props.open && this.props.open !== prevProps.open) {
this.props.scheduleUpdate();
}
}
render() {
return (
<div className={`dayPickerOverlay ${this.state.showDatePicker ? "" : "hidden"}`} ref={ref} style={style} data-placement={placement}>
<DateRangePicker />
</div>
);
}
}
// App.js
<Manager>
<Reference>
{({ ref }) => (
<button ref={ref} onClick={this.onDateRangeBtnClick}>click to show</button>
)}
</Reference>
{ReactDOM.createPortal(
<Popper placement="auto-end">
{({ ref, style, placement, arrowProps, scheduleUpdate }) => (
<PopperElement open={this.state.open} scheduleUpdate={scheduleUpdate} />
)}
</Popper>,
document.querySelector('#root')
)}
</Manager>
If you prefer a more concise approach, I think I'd use react-powerplug this way:
import { Manager, Popper, Reference } from 'react-popper';
import { State } from 'react-powerplug';
const App = () => (
<Manager>
<Popper>
{({ ref, style, scheduleUpdate }) => (
<State initial={{ open: false }} onChange={scheduleUpdate}>
{({ state, setState }) => (
<Fragment>
<Reference>
{({ ref }) => (
<button
ref={ref}
onClick={() => setState({ open: true }})
>click to show</button>
)}
</Reference>
{open && <YourContent ref={ref} style={style} />}
</Fragment>
)}
</State>
)}
</State>
</Manager>
);
I avoided to repeat the React.createPortal part for conciseness, it should be in place of YourContent.

React rendering user list in child component

In my parent component (a search bar component) I have this code which passes an array down to the child component:
When form is submitted I make am axios request to my back-end database
async onFormSubmit(event) {
event.preventDefault();
const users = await axios.post("/api/fetchuser", {
persona: this.state.term
});
let userArray = this.state.userArray;
userArray = users.data.map(user => {
return user.steamInfo;
});
this.setState({ userArray: userArray });
}
Then I pass down the userArray to the child component:
renderResults() {
if (this.state.userArray.length > 0) {
return <UserSearchResult userArray={this.state.userArray} />;
} else {
return;
}
}
In my child component I have this, keep note of the console.logs as I will show the output afterwards.
class UserSearchResult extends Component {
async renderUsers() {
let userList = this.props.userArray;
console.log(userList);
userList = userList.map(user => {
return (
<Segment>
<Grid>
<Grid.Column width={3} style={resultStyle.results}>
<Image src={user.avatar} fluid />
</Grid.Column>
<Grid.Column width={9} />
<Grid.Column width={3} />
</Grid>
</Segment>
);
});
console.log(userList);
return userList;
}
render() {
return (
<div>
{console.log(this.renderUsers())}
</div>
);
}
}
Here is the output:
In the first two console.logs, it prints out exactly what I want, but once I return the userList back to the render function, it changes into promises?
My question is: Why is the userList changing to something else when it's returned to the render function. And how can I render each element in the array according to my jsx?
Try removing async. async makes your function return a promise which isn't necessary.
Also UserSearchResult doesn't need to be a class, just do this.
const UserSearchResult = (props) => {
const userList = this.props.userArray;
console.log(userList);
const UserDetail = ({user}) => {
return (
<Segment>
<Grid>
<Grid.Column width={3} style={resultStyle.results}>
<Image src={user.avatar} fluid />
</Grid.Column>
<Grid.Column width={9} />
<Grid.Column width={3} />
</Grid>
</Segment>
);
console.log(userDetail);
return (
<div>
{userList.map((user, index) => <UserDetail key={index} user={user} /> )}
</div>
);
}
Or you could just {userList.map((user, index) => <UserDetail key={index} user={user} /> )} in your original component and make UserDetail it's own component and get rid of the UserSearchResult.
You should remove the async portion. I believe that is what the root of your issue is. I refactored your code below:
class UserSearchResult extends Component {
render() {
const { userArray } = this.props
return (
<div>
{ userArray.map(user => {
return (
<Segment>
<Grid>
<Grid.Column width={3} style={resultStyle.results}>
<Image src={user.avatar} fluid />
</Grid.Column>
<Grid.Column width={9} />
<Grid.Column width={3} />
</Grid>
</Segment>
);
});
}
</div>
);
}
}

Categories

Resources