-
Notifications
You must be signed in to change notification settings - Fork 0
Clever Snippets
14paxton edited this page Aug 10, 2023
·
11 revisions
title: Clever-Snippets
permalink: ReactNotes/Clever-Snippets
category: ReactNotes
parent: ReactNotes
layout: default
has_children: false
share: true
shortRepo:
- clever-snippets
- default
Table of contents
{: .text-delta } 1. TOC {:toc}# Print separate page from current page
const [, updateState] = React.useState();
const forceUpdate = React.useCallback(() => updateState({}), []); const RecursiveWrapper = props => {
const wrappedChildren = React.Children.map(props.children, child => {
if (child.props && child.props.children) {
return <RecursiveWrapper>
{child.props.children}
</RecursiveWrapper>
}
return <div>
{'children: 0'}
</div>
})
return <React.Fragment>
{`children: ${wrappedChildren.length}`}
<div>
{wrappedChildren}
</div>
</React.Fragment>
} import React, {forwardRef, useCallback, useEffect, useState} from "react";
import PropTypes from "prop-types";
import {styled} from "@material-ui/styles";
const ChildContainer = styled('div')({});
const RecursiveComponent = forwardRef(({parentRefHandler, nodeNameOrIdArray, children, ...rest}, ref) => {
const [containerRef, setContainerRef] = useState(null);
const [elementMounted, setElementMounted] = useState();
const [elementRef, setElementRef] = useState(null);
const [childrenObject, setChildrenObject] = useState({});
//passing callback to ref will set a container reference
const setContainer = useCallback((element) => {
if (element && !elementRef?.current && (nodeNameOrIdArray.indexOf(elementRef?.current?.nodeName) === -1 || nodeNameOrIdArray.indexOf(elementRef?.current?.nodeName) === -1)) {
const innerContainer = element.firstElementChild
innerContainer.id = `RecursiveComponent_Child_Container`
setContainerRef(innerContainer)
}
}, [children],);
//once container ref is set, we know the element has mounted
useEffect(() => {
if (containerRef) {
setElementMounted(true)
}
}, [containerRef]);
//once the element has mounted we need to query the child elements for any ids or element names that were passed in
// from the nodeNameOrIdArray prop
//if the element is found it will be added to the object with the name in the array
// all unspecified children will be put in an array
useEffect(() => {
if (containerRef && elementMounted === true && containerRef.children) {
const children = {unnamedChildren: []}
for (const el of containerRef.children) {
let foundElement
nodeNameOrIdArray.forEach((name, index) => {
foundElement = el.querySelector(name)
if (foundElement) {
foundElement.id = `${name}_${index}`
? `${name}_${index}`
: `nested_element_id_${index}`
children[name] = foundElement
}
})
if (!foundElement) children.unnamedChildren.push(el)
}
setElementRef(ref)
setChildrenObject(children)
}
}, [elementMounted]);
//after seting a reference to the needed element we can run the method/handler that was passed down
useEffect(() => {
if (parentRefHandler && childrenObject) {
parentRefHandler(childrenObject)
}
}, [childrenObject]);
return (<ChildContainer ref={setContainer}>
{React.cloneElement(children, rest)}
</ChildContainer>);
})
RecursiveComponent.propTypes = {
children: PropTypes.instanceOf(Object), nodeNameOrIdArray: PropTypes.array
}
RecursiveComponent.defaultProps = {
nodeNameOrIdArray: []
}
export default RecursiveComponent const WebApp = (props) => {
return <div>
{config.map((componentName) => {
componentMapping[componentName]
return <Component/>;
})}
</div>
}; import React, {useState, useEffect} from 'react';
import './style.css';
export default function App() {
const [user, setUser] = useState(false);
const [scriptLoadingState, setScriptLoadingState] = useState('IDLE');
useEffect(() => {
if (user) {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://www.google-analytics.com/analytics.js';
script.onload = function () {
setScriptLoadingState('LOADED');
};
script.onerror = function () {
setScriptLoadingState('FAILED');
};
document.body.appendChild(script);
}
}, [user]);
return (<div>
<button
onClick={() => setUser(true)}
style={{width: '200px', height: '30px', fontSize: '16px'}}
>
Login
</button>
<h2>
Script Loading State:{' '}
<span
style={{
color: scriptLoadingState === 'IDLE'
? 'grey'
: scriptLoadingState === 'LOADED'
? 'green'
: 'red',
}}
>
{scriptLoadingState}
</span>
</h2>
</div>);
} <Link to={`/products/${product.id}`}>{product.name}</Link> Rather than
<a>
Ul > (li[className = 'test']) // create ref
Const
username = React.createRef()
// [setreference]
< input
ref = {this.username}
id = "username"
type = "text"
className = "form-control" / >
// use ref
const username = this.username.current.value; - alt
const element = <div ref={ref}/>;
// ...
ref.current; // DOM element
- alt
export default function Component(props) {
const nodeRef = useRef();
useEffect(() => {
console.log(nodeRef.current);
}, []);
// Root Node
return <input ref={nodeRef}/>;
} {
error && <div className="alert
alert-danger">{error}</div>
} Used to update 1 or more properties
Axios.patch(apiEndpoint + '/' + post.id, {title: post.title}); Update all properties
axios.put(apiEndpoint + '/' + post.id, post) axios.interceptors.response.use(success, error)
this.props.history.push('/'); this.props.history.push('/'); localStorage.setItem('token', response.headers['x-auth-token']); set local storage and access response header, need to have backend make headers visible> set local storage and access response header, need to have backend make headers visible
.header("access-control-expose-headers", "x-auth-token")
{ __html: '<p>' + result?.themeSummary + '. <i>Theme Of Significance.</i></p> '}
< Tooltip title={<div dangerouslySetInnerHTML={modifiedToolTip}/>} childrenDisplayStyle="inline"> used after browser repaints DOM
react will prioritize UI
React.useEffect(() => {
// Will be invoked on the initial render
// and all subsequent re-renders.
}) React.useEffect(() => {
// Will be invoked on the initial render
// and when "id" or "authed" changes.
}, [id, authed]) React.useEffect(() => {
// Will only be invoked on the initial render
}, []) React.useEffect(() => {
return () => {
// invoked right before invoking
// the new effect on a re-render AND
// right before removing the component
// from the DOM
}
}) useEffect(() => {
return () => console.log('unmounting...');
}) useEffect(() => {
let isMounted = true;
register('interviewModelId');
fetchInterviewModels().then((data) => {
if (isMounted) setAssessmentChoiceList(data);
setSelectedInterviewModel(data);
});
if (!groupDetails) {
register({name: 'assessmentOrderIds'}, {
required: errorMessages.assIdsRequired, validate: (value) => value.length <= maxGroupMembers || errorMessages.maxGroupMembers
});
}
return () => {
isMounted = false;
};
}, [errorMessages.assIdsRequired, errorMessages.maxGroupMembers, groupDetails, maxGroupMembers, register, setSelectedInterviewModel]);