I use props.children in function component like below which is working fine as in all children renders fine in UI.
function Footer(props: FooterProps) {
return (
<div>
{props.children}
</div>
);
};
However, I need to filter the props.children based on some properties of child and put them in different div. There are no errors in console, but child components does not render.
function Footer(props: FooterProps) {
return (
<div>
{props.children?.map(child => {
if (child.align === "right") { //no probs with this condition, code executes as expected.
<div> // grouping into another div
{child}
</div>
}
else {
{ child }
}
})}
</div>
);
};
Any idea what could be wrong here?
You aren't returning anything in your map callback, it's becoming an array of undefined which React is designed not to render anything for. If you wrap your two intended values in return statements it should work as intended.
Here's what that would look like:
function Footer(props: FooterProps) {
return (
<div>
{props.children?.map(child => {
if (child.align === "right") { //no probs with this condition, code executes as expected.
return (
<div> // grouping into another div
{child}
</div>
);
}
else {
return child;
}
})}
</div>
);
};
I'm not sure if this is really the correct way to do this, generally speaking I'd discourage changing a child directly in this way after receiving it and looking for a more compositional approach, but in the case that you do need to do so, you might should be using the React.Children.map method: https://reactjs.org/docs/react-api.html#reactchildrenmap
Related
I am using my lit element like this
<my-header>MyHeading</my-header>
And I have my lit element's render method:
render() {
return html`
<h3><slot></slot></h3>
`;
}
which is working perfectly. Now I want the inner content i.e. "MyHeading" in my lit element's class as a value(not to render). Is there any way to get that innerHTML or as a text?
Note: my use case can be to set another property of rendered content like
render() {
return html`
<h3 id="${//How to get that 'MyHeading' here??}"><slot></slot></h3>
`;
}
Is it possible to get inner content as a value?
This is what you get when you learn new stuff starting with a Library or Framework;
You learn the Tool, not the Technology.
The child-elements of your customElement are not available yet
when the connectedCallback fires
so you wait till the EventLoop is empty (and thus know all children are parsed)
Or use any of the Library methods that (usually) fire even later than a setTimeout
Or, even more blunty, like many blogs show, execute the script that creates your Element
after the whole DOM is parsed by marking it a type="module" or async or defer
<script>
customElements.define("my-element", class extends HTMLElement {
constructor(){
super().attachShadow({mode:"open"}).innerHTML = `<h3><slot></slot></h3>`
}
connectedCallback() {
setTimeout(() => { // wait till innerHTML is parsed
let title = this.innerText;
console.log("Reflected from lightDOM:" , title);
this.shadowRoot.querySelector("h3").id = title;
})
}
})
</script>
<my-element>
Hello Web Components!
</my-element>
i have minimal reproduce here https://stackblitz.com/edit/angular-uwfsyv?file=app%2Fapp.component.html, there i have 2 array,checkboxesDataList and checkboxesDataList2 i successfully get the checked label from checkboxesDataList but that's just for an example.
but what i wanted to get in my project is similar to checkboxesDataList2 inside here i have object question and checkboxesDataList don't have that so this function
fetchSelectedItems() {
this.selectedItemsList = this.checkboxesDataList.filter((value, index) => {
return value.checked;
});
}
won't work immediately if i change this.checkboxesDataList to this.checkboxesDataList2 how can i make it work?
do you want to has a function like?
getDataChecked()
{
return this.checkboxesDataList2.question
.map(x=>x.options.filter(o=>o.checked))
.reduce((acc, value)=>[...acc,...value])
}
Im creating a webpage in which users can post stuff to a "bulletin board". These posts are gonna be styled as boxes, and I want to add them to a grid layout. This is my code:
import React from 'react';
//import Gallery from "./components/gallery.component"
function App() {
state = {
posts = [];
};
componentDidMount = () => {
this.getPosts();
};
getPosts = () => {
axios.get('(server)')
.then((response) => {
const data = response.data;
this.setState({ posts: data });
})
}
displayBlogPost = (posts) => {
if (!posts.length) return null;
return posts.map((post, index) => (
<div key={index} className="post__display">
<h3>"name " + this.state.name </h3>
</div>
));
};
render() {
return (
<div className="App">
<header className="container">
Logo
</header>
</div>
<div className="gallery">
{this.displayBlogPost(this.state.posts)} </div>
)
}
}
export default App;
Im a little unsure of how to work on the grid. Ive been looking into the CSS Grid documentation and I was wondering if it would be enough to keep my code as is and create a css file with an id #gallery that sets the attributes of the grid (display, grid-gap, repeat, etc). Would this be enough, or will I have to change my displayBlogPost function. I'm worried that the approach will consider gallery just containing one element and therefore there wont even be a grid.
Would appreciate some clarification and suggestions, I tried to find examples online, but none seemed to use react, mongodb, and css grid.
Its also hard because Im a newbie to React and MongoDB and JavaScript in general, but this project is for a hackathon and Im on a time crunch
Even though the post contains only one element the HTML DOM would show the grid in itself.
Yes, you can create a separate CSS file and include the req. CSS there.
Also, "name " + this.state.name you have not defined the state "name", how are you expecting for a display of value there?
Is there any way in which I could test say the height css property of an element?
I have a function that changes the height of a div and it would be nice to check in the tests that the function operates correctly...
ie:
<div #myDiv>Hello world</div>
#ViewChild('myDiv') myDiv: ElementRef;
myFunct() {
this.myDiv.nativeElement.style.height = 500;
}
it('should increase div size', () => {
// Here is where I get stuck...
});
Update
Implementing a test such as:
it('should return correct height of dropdown when initialised', () => {
component.myFunct();
expect(component.dropdown.nativeElement.style.height).toBe(34);
});
results in a test failure with message:
Expected '' to be 500.
Something like this...
Exposed the myDiv publicly
Setup the testbed for the component (usually added by default)
Add
component.myFunct();
expect(component.myDiv.nativeElement.style.height).toBe(500);
I'm given an HTML string from an API:
<div><h1>something</h1><img src="something" /></div>
I would like to add an onClick handler onto the img tag. I thought about using regex replace, but it's highly advised against.
I'm new to React... how would you go about solving this problem?
Any links or pointing into the right direction would be highly appreciated!
EDIT
Is there a way to add a listener to all anchor tags in a react friendly way? I'm thinking then I can just check the anchor tag's children, and if there's an image element, then I can run my code block.
I think a more idiomatic React way of doing this would be to refactor this into a component, replete with it's own onClick handler, and then insert your image URL via props. Something like
class MyImg extends React.Component {
onClick() {
// foo
}
render() {
return (
<div onClick={this.onClick}>
<h1>{this.props.foo}</h1>
<img src={this.props.imgSrc} />
</div>
);
}
}
Can you update your API to return JSON instead of HTML? JSON is easier to manipulate and you can create react elements on the fly, for example, let's assume your API returns this:
{
component: 'div',
children: [
{ component: 'h1', text: 'Something here' },
{ component: 'img', src: 'something.jpg' },
],
}
If you have that kind of response is very easy to create React elements at run time, you can also add events when creating these components, for example:
class DynamicContent extends PureComponent {
onImageClick = () => {
// Do something here!
console.log('Testing click!');
}
render() {
const children = response.children;
return React.createElement(response.component, null,
React.createElement(children[0].component, null, children[0].text),
React.createElement(children[1].component, {
...children[1],
onClick: this.onImageClick, // <-- Adds the click event
}),
);
}
}
You might want to create an utility that dynamically walks through the response object and creates all the components that you need.