React
...see more

When building tree structures in React, you might see this warning:

"Encountered two children with the same key..."

This usually happens when your component is rendering a list or tree and uses the same key value for multiple items. React requires that keys be unique among siblings to correctly track changes.

The Problem

In some apps, a tree of items is built using IDs like id, targetId, and parentId. A common mistake is using a field like targetId as the unique key — but if that field isn't truly unique, React throws an error.

Also, when building the tree structure, developers often assume that parentId matches a node’s id, but sometimes it actually matches others like targetId — and since targetId isn't unique, that causes lookup problems.

The Fix

Here’s how to correctly build the tree and avoid duplicate keys:

  1. Use id as the unique key — it's meant to be unique and stable.
  2. Create a dictionary keyed by id.
  3. Build a helper map from targetId to nodes — since targetId isn't unique, store an array of nodes per targetId.
  4. When assigning children, match parentId to the corresponding targetId, and attach the node to all matches (if multiple).

Here’s a simplified version of the corrected tree builder:

function buildTree(nodes) {
  const updatedNodes = nodes.map(node => ({
    ...node,
    id: String(node.id),
    targetId: String(node.targetId),
    parentId: String(node.parentId),
    children: [],
  }));

  const targetIdToNodes = {};
  updatedNodes.forEach(node => {
    if (!targetIdToNodes[node.targetId]) {
      targetIdToNodes[node.targetId] = [];
    }
    targetIdToNodes[node.targetId].push(node);
  });

  const rootNodes = [];

  updatedNodes.forEach(node => {
    if (node.parentId === '0') {
      rootNodes.push(node);
    } else {
      const parents = targetIdToNodes[node.parentId];
      if (parents) {
        parents.forEach(parent => {
          parent.children.push(node);
        });
      }
    }
  });

  return rootNodes;
}

In your React rendering, always use node.id for the key:

<TreeNode key={node.id} node={node} />

Takeaway

Always make sure your keys in React are unique and stable. And when building a tree, know what your parentId is pointing to — it can make or break your structure.

...see more

JSX may look like HTML, but it’s actually JavaScript. When used correctly, it brings power and clarity to React development.

Why Use JSX?

  • It’s familiar to anyone who has written HTML.
  • You can mix logic and layout using {} for JavaScript expressions.
  • JSX is compiled into fast and efficient React code.

Key JSX Rules

  • Use className instead of class.
  • Self-closing elements like <img />.
  • Wrap multiple elements in one parent: <div> or <>.

Example:

function Greeting() {
  return <h1>Hello, world!</h1>;
}

Common Mistakes

  • Forgetting to close tags.
  • Using class instead of className.
  • Returning multiple sibling elements without a wrapper.
...see more

When using ref in React, especially with forwardRef, it's important to understand how ref works — and how it doesn't.

The Problem

You might see this warning in your console:

ref is not a prop. Trying to access it will result in undefined being returned...

This usually happens when you try to declare ref in your component's propTypes or access it like a normal prop (props.ref). But ref is a special prop in React. It doesn't behave like other props.

✅ The Correct Way to Use ref

When using forwardRef, React gives the ref as the second argument of your function. Here's what that looks like:

const MyComponent = forwardRef(function MyComponent(props, ref) {
  // use ref directly
});

Don't try to access ref through props.ref. That won't work.


❌ Don't Do This

MyComponent.propTypes = {
  // This will trigger a warning!
  ref: PropTypes.any,
};

React doesn't pass ref through the normal props object, so it shouldn’t be validated with propTypes.


The Fix

  • Use ref only via the second argument in forwardRef.
  • Remove ref from propTypes.

This will prevent the warning and adhere to React best practices.

...see more

If you're using TinyMCE in a React app and want to provide users with a way to remove all data-* attributes from their content, you can create a custom toolbar button to do just that.

Why do this?

data-* attributes are often added by frameworks, plugins, or tracking tools. In some cases, you might want to remove these before saving or publishing content, especially for clean, production-ready HTML.

How to Add the Button

You can use TinyMCE’s setup function to add a custom button with a mop-like icon to your toolbar. Here's how:

import { Editor } from '@tinymce/tinymce-react';

function MyEditor({ content, contentChange, onEditorInit }) {
  return (
    <Editor
      value={content}
      onEditorChange={(newValue) => contentChange(newValue)}
      onInit={onEditorInit}
      init={{
        height: 500,
        menubar: false,
        plugins: 'code',
        toolbar: 'undo redo | mopCleaner | bold italic underline | code',
        setup: (editor) => {
          editor.ui.registry.addIcon('mopCleanerIcon', `
            <svg width="24" height="24" viewBox="0 0 24 24">
              <path d="M12 2v14" stroke="currentColor" stroke-width="2"/>
              <path d="M8 16h8l1 4H7l1-4z" fill="currentColor"/>
            </svg>
          `);

          editor.ui.registry.addButton('mopCleaner', {
            icon: 'mopCleanerIcon',
            tooltip: 'Remove all data-* attributes',
            onAction: () => {
              const currentContent = editor.getContent();
              const cleanedContent = currentContent.replace(/\sdata-[\w-]+="[^"]*"/g, '');
              editor.setContent(cleanedContent);
            },
          });
        },
      }}
    />
  );
}

How it works:

  • The button removes all HTML attributes that match the pattern data-something="value".
  • It works even when multiple data-* attributes are in a single tag.
  • You can customize the icon or tooltip to match your app's style.

Tip:

To support edge cases, such as attributes with single quotes or no values, you can enhance the regex as needed.

...see more

TinyMCE is a popular rich text editor used to add content-editing capabilities to web apps. When working with React, TinyMCE provides an official wrapper that makes integration quick and easy.

Here’s how to set it up in a React project:

1. Install the Package

Use npm:

npm install @tinymce/tinymce-react

2. Basic Usage

Import the component and render it:

import { Editor } from '@tinymce/tinymce-react';

function MyEditor() {
  return (
    <Editor
      initialValue="<p>Start typing...</p>"
      init={{
        height: 300,
        menubar: false,
        plugins: 'link image code',
        toolbar: 'undo redo | formatselect | bold italic | link image | code',
      }}
    />
  );
}

This will render a fully functional rich text editor inside your React component.

3. Handling Content Changes

You can capture changes to the editor content like this:

<Editor
  onEditorChange={(newContent) => {
    console.log(newContent); // Save or process the content here
  }}
/>

Tips:

  • TinyMCE is highly customizable with plugins, themes, and custom toolbars.

  • You can host TinyMCE locally or use the cloud version.

  • It supports custom buttons, icons, and content filtering.


Learn More:

Visit TinyMCE React Docs for advanced configuration options.

...see more

JavaScript Date objects are always created and manipulated relative to the user’s local timezone, which it gets from the environment.

const date = new Date("2025-05-27T20:03:00Z"); // stored as UTC
console.log(date.toString()); 
// → "Tue May 27 2025 22:03:00 GMT+0200 (Central European Summer Time)"

To determine the client’s timezone:

Intl.DateTimeFormat().resolvedOptions().timeZone
// → "Europe/Berlin" or similar

This automatic timezone handling is key to understanding how UTC inputs appear offset when viewed or edited on the frontend.

...see more

To display datetimes in the user's local timezone while preserving backend UTC storage, you can use JavaScript's built-in timezone offset support:

const utcDate = "2025-05-27T20:03:00Z";
const localDisplay = new Date(utcDate).toLocaleString();
// → "5/27/2025, 10:03 PM" (depending on user's locale)

This gives users a familiar and correctly adjusted view of time. For a consistent format, Intl.DateTimeFormat can be used.

...see more

ASP.NET Core with System.Text.Json handles ISO 8601 UTC strings automatically when binding to DateTime properties. Ensure you're not converting to UTC again if the incoming data already ends with Z.

Best Practices:

 

[JsonPropertyName("created")]
public DateTime Created { get; set; } // Will be parsed as UTC if ends in "Z"

If needed, ensure correct serialization:

private readonly JsonSerializerOptions _jsonOptions = new()
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
    DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
    Converters = { new UtcDateTimeConverter() }
};

Custom converter (if required):

public class UtcDateTimeConverter : JsonConverter<DateTime>
{
    public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        => DateTime.SpecifyKind(reader.GetDateTime(), DateTimeKind.Utc);

    public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
        => writer.WriteStringValue(value.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ"));
}
...see more

When a user selects a datetime in a <input type="datetime-local">, the returned value (e.g., "2025-05-27T22:03") is in local time. To maintain UTC consistency on the backend, this must be converted to UTC.

Implementation:

const handleChange = (e) => {
  const local = new Date(e.target.value); // local time
  const utc = local.toISOString();        // UTC string for API
  setPost({ ...post, created: utc });
};

This ensures accurate time data regardless of the user's timezone.

...see more

To populate an <input type="datetime-local"> in React, you must convert your UTC string into a local time string formatted as "yyyy-MM-ddTHH:mm" — the only format the input accepts.

Implementation:

function toDatetimeLocalValue(dateInput) {
  const date = new Date(dateInput);
  const pad = (n) => n.toString().padStart(2, '0');

  return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}T${pad(date.getHours())}:${pad(date.getMinutes())}`;
}

Use this function when binding input values in forms to ensure users see time in their own timezone.

Add to Set
  • .NET
  • Agile
  • AI
  • ASP.NET Core
  • Azure
  • C#
  • Cloud Computing
  • CSS
  • EF Core
  • HTML
  • JavaScript
  • Microsoft Entra
  • PowerShell
  • Quotes
  • React
  • Security
  • Software Development
  • SQL References
  • Technologies
  • Testing
  • Visual Studio
  • Windows
 
Sets