Reputation: 83
Im new to React and TS. I'm trying to pass an accesskey from parent to child in a react route.
When console.logging on parent, I have the key, but it doesnt seem I'm able to pass the key down to the child. I've been trying around for a couple of hours with no luck what so ever. Any advice/help?
Parent:
let token = ""
function ActiveLink({to, children, ...props} : any){
const resultPath = useResolvedPath(to)
const isActive = useMatch({path: resultPath.pathname, end:true})
return(
<li className={isActive? "active" : ""}>
<Link to={to} {...props}>
{children}
</Link>
</li>
)
}
type AppProps = {
pca: IPublicClientApplication
};
function ProfileContent() {
const { instance, accounts } = useMsal();
const [graphData, setGraphData] = useState<any | null>(null);
const [accessToken, setAccessToken] = useState<any | null>("");
var name = accounts[0] && accounts[0].name;
var name = name?.split(',')[1];
React.useEffect(() => {
const request = {
...loginRequest,
account: accounts[0]
};
// Silently acquires an access token which is then attached to a request for Microsoft Graph data
instance.acquireTokenSilent(request).then((response) => {
callMsGraph(response.accessToken).then(response => setGraphData(response));
setAccessToken(response.accessToken)
token = response.accessToken;
}).catch((e) => {
instance.acquireTokenPopup(request).then((response) => {
callMsGraph(response.accessToken).then(response => setGraphData(response));
});
});
},[]);
return (
<>
<p className="card-title">Velkommen tilbake,</p>
<h5 className="navBar-name">{name}</h5>
<h5></h5>
<Link to="/oversikt" className="test">Min oversikt</Link>
<Link to="/oppdrag" className="test">Mine oppdrag</Link>
<Link to="/ansvarsområde" className="test">Mitt ansvarsområde</Link>
{graphData && accessToken?
<div>
<ProfileData graphData={graphData}/>
<ProfilePic accessToken={accessToken}/>
</div>
:
<h5>Something bad happened, error!</h5>
}
</>
);
};
function App({ pca }: AppProps) {
return (
<div>
<nav>
<MsalProvider instance={pca}>
<Routes>
<Route path = "/oversikt" element={<Oversikt/>}/>
<Route path = "/oppdrag/*" element={<Mineoppdrag/>}/>
<Route path = "/oppdrag/rapport"element= {<PowerBIClient accessToken={token}/>}/>
<Route path = "/ansvarsområde" element={<Ansvarsområde/>}/>
<Route path = "/login" element={<UnauthenticatedTemplate/>}/>
</Routes>
<PageLayout>
<AuthenticatedTemplate>
<div id ="container">
<ProfileContent/>
</div>
</AuthenticatedTemplate>
<UnauthenticatedTemplate>
<div className="signinText">You are not signed in. Please sign in!</div>
</UnauthenticatedTemplate>
</PageLayout>
</MsalProvider>
</nav>
</div>
);
}
export default App;
Child:
interface myProps {
accessToken: string,
}
declare global {
interface Window {
report:any;
}
}
export default class PowerBIClient extends React.Component<myProps> {
public render() {
console.log(this.props.accessToken + "TOKEN")
return (
<PowerBIEmbed
embedConfig = {
{
type: 'report', // Supported types: report, dashboard, tile, visual, and qna.
embedUrl: "url",
accessToken: this.props.accessToken,
tokenType: models.TokenType.Aad, for your organization.
settings: {
panes: {
filters: {
expanded: false,
visible: true
}
},
}
}
}
eventHandlers = {
new Map([
['loaded', function () {
console.log('Report loaded');
}],
['rendered', function () {
console.log('Report rendered');
}],
['error', function (event:any) {
console.log(event.detail);
}]
] )
}
cssClassName = {
"Embed-container"
}
getEmbeddedComponent = {
(embeddedReport) => {
window.report = embeddedReport;
console.log(this.props.accessToken + "TOKEN")
}
}
/>
)
}
}
UPDATE:
function ActiveLink({to, children, ...props} : any){
const resultPath = useResolvedPath(to)
const isActive = useMatch({path: resultPath.pathname, end:true})
return(
<li className={isActive? "active" : ""}>
<Link to={to} {...props}>
{children}
</Link>
</li>
)
}
type AppProps = {
pca: IPublicClientApplication
};
function ProfileContent({accessToken, setAccessToken}:any) {
const { instance, accounts } = useMsal();
const [graphData, setGraphData] = useState<any | null>(null);
//const [accessToken, setAccessToken] = useState<any | null>("");
var name = accounts[0] && accounts[0].name;
var name = name?.split(',')[1];
React.useEffect(() => {
const request = {
...loginRequest,
account: accounts[0]
};
// Silently acquires an access token which is then attached to a request for Microsoft Graph data
instance.acquireTokenSilent(request).then((response) => {
callMsGraph(response.accessToken).then(response => setGraphData(response)).catch((e) =>{
console.log(e)
}
)
if(response.accessToken)
setAccessToken(response.accessToken)
console.log(accessToken + "TOKEN")
}).catch((e) => {
console.log(e , "TokenPopUPError")
instance.acquireTokenPopup(request).
then((response) => {
callMsGraph(response.accessToken)
.then(response => setGraphData(response));
setAccessToken(response.accessToken)
});
});
},[]);
return (
<>
<p className="card-title">Velkommen tilbake,</p>
<h5 className="navBar-name">{name}</h5>
<h5></h5>
<Link to="/oversikt" className="test">Min oversikt</Link>
<Link to="/oppdrag" className="test">Mine oppdrag</Link>
<Link to="/ansvarsområde" className="test">Mitt ansvarsområde</Link>
{graphData && accessToken?
<div>
<ProfileData graphData={graphData}/>
<ProfilePic accessToken={accessToken}/>
</div>
:
<h5>Something bad happened, error!</h5>
}
</>
);
};
function App({ pca }: AppProps) {
const [accessToken, setAccessToken] = useState<string>();
return (
<div>
<nav>
<MsalProvider instance={pca}>
<Routes>
<Route path = "/oversikt" element={<Oversikt/>}/>
<Route path = "/oppdrag/*" element={<Mineoppdrag/>}/>
<Route path = "/oppdrag/rapport"element= {<PowerBIClient accessToken={accessToken}/>}/>
<Route path = "/ansvarsområde" element={<Ansvarsområde/>}/>
<Route path = "/login" element={<UnauthenticatedTemplate/>}/>
</Routes>
<PageLayout>
<AuthenticatedTemplate>
<div id ="container">
<ProfileContent accessToken={accessToken}/>
</div>
</AuthenticatedTemplate>
<UnauthenticatedTemplate>
<div className="signinText">You are not signed in. Please sign in!</div>
</UnauthenticatedTemplate>
</PageLayout>
</MsalProvider>
</nav>
</div>
);
}
export default App;
Upvotes: 1
Views: 1033
Reputation: 203587
Move the accessToken
state up to the common ancestor, the App
component and pass it and the state updater function down to the descendent components that need to access it.
See Lifting State Up for more details.
Example:
function App({ pca }: AppProps) {
const [accessToken, setAccessToken] = useState<string>(""); // <-- declare state
return (
<div>
<nav>
<MsalProvider instance={pca}>
<Routes>
<Route path="/oversikt" element={<Oversikt />} />
<Route path="/oppdrag/*" element={<Mineoppdrag />} />
<Route
path="/oppdrag/rapport"
element= {<PowerBIClient accessToken={accessToken} />} // <-- pass down as props
/>
<Route path="/ansvarsområde" element={<Ansvarsområde />} />
<Route path="/login" element={<UnauthenticatedTemplate />} />
</Routes>
<PageLayout>
<AuthenticatedTemplate>
<div id ="container">
<ProfileContent {...{ accessToken, setAccessToken }}/> // <-- pass down as props
</div>
</AuthenticatedTemplate>
<UnauthenticatedTemplate>
<div className="signinText">
You are not signed in. Please sign in!
</div>
</UnauthenticatedTemplate>
</PageLayout>
</MsalProvider>
</nav>
</div>
);
}
...
function ProfileContent({ accessToken, setAccessToken }) {
const { instance, accounts } = useMsal();
const [graphData, setGraphData] = useState<any | null>(null);
var name = accounts[0] && accounts[0].name;
var name = name?.split(',')[1];
React.useEffect(() => {
const request = {
...loginRequest,
account: accounts[0]
};
// Silently acquires an access token which is then attached to a request for Microsoft Graph data
instance.acquireTokenSilent(request)
.then((response) => {
callMsGraph(response.accessToken)
.then(response => setGraphData(response));
setAccessToken(response.accessToken);
})
.catch((e) => {
instance.acquireTokenPopup(request)
.then((response) => {
callMsGraph(response.accessToken)
.then(response => setGraphData(response));
});
});
}, []);
return (
<>
<p className="card-title">Velkommen tilbake,</p>
<h5 className="navBar-name">{name}</h5>
<h5></h5>
<Link to="/oversikt" className="test">Min oversikt</Link>
<Link to="/oppdrag" className="test">Mine oppdrag</Link>
<Link to="/ansvarsområde" className="test">Mitt ansvarsområde</Link>
{graphData && accessToken
? (
<div>
<ProfileData graphData={graphData}/>
<ProfilePic accessToken={accessToken}/>
</div>
) : (
<h5>Something bad happened, error!</h5>
)}
</>
);
};
Upvotes: 1